Zelda Classic Coverage Report


Directory: src/
File: src/guys.cpp
Date: 2022-12-17 23:02:17
Exec Total Coverage
Lines: 3415 11775 29.0%
Functions: 167 424 39.4%
Branches: 2664 14574 18.3%

Line Branch Exec Source
1 //--------------------------------------------------------
2 // Zelda Classic
3 // by Jeremy Craner, 1999-2000
4 //
5 // guys.cc
6 //
7 // "Guys" code (and other related stuff) for zelda.cc
8 //
9 //--------------------------------------------------------
10
11 #include "precompiled.h" //always first
12
13 #include <string.h>
14 #include <stdio.h>
15 #include "base/zc_alleg.h"
16
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 #include "guys.h"
17 #include "zelda.h"
18 #include "base/zsys.h"
19 #include "maps.h"
20 #include "hero.h"
21 #include "subscr.h"
22 #include "ffscript.h"
23 #include "gamedata.h"
24 #include "defdata.h"
25 #include "zscriptversion.h"
26 #include "particles.h"
27 #include "base/zc_math.h"
28 #include "slopes.h"
29 extern particle_list particles;
30
31 extern FFScript FFCore;
32 extern word item_doscript[256];
33 extern refInfo itemScriptData[256];
34 extern int32_t item_stack[256][MAX_SCRIPT_REGISTERS];
35 extern ZModule zcm;
36 extern HeroClass Hero;
37 extern sprite_list guys, items, Ewpns, Lwpns, Sitems, chainlinks, decorations;
38 extern zinitdata zinit;
39
40 int32_t repaircharge=0;
41 bool adjustmagic=false;
42 bool learnslash=false;
43 int32_t wallm_load_clk=0;
44 int32_t sle_x,sle_y,sle_cnt,sle_clk=0;
45 int32_t vhead=0;
46 int32_t guycarryingitem=0;
47
48 char *guy_string[eMAXGUYS];
49
50 void never_return(int32_t index);
51 void playLevelMusic();
52
53 // If an enemy is this far out of the playing field, just remove it.
54 #define OUTOFBOUNDS ((int32_t)y>((isSideViewGravity() && canfall(id))?192:352) || y<-176 || x<-256 || x > 512)
55 //#define NEWOUTOFBOUNDS ((int32_t)y>32767 || y<-32767 || x<-32767 || x > 32767)
56 #define IGNORE_SIDEVIEW_PLATFORMS (editorflags & ENEMY_FLAG14)
57 #define OFFGRID_ENEMY (editorflags & ENEMY_FLAG15)
58
59 8816 void do_fix(zfix& coord, int32_t val, bool nearest_half = false)
60 {
61 8816 int32_t c = coord.getInt();
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8816 times.
8816 if(nearest_half)
63 {
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8816 times.
8816 if (c < 0)
65 c -= val / 2;
66 8816 else c += (val/2);
67 8816 }
68 8816 c -= c % val;
69 8816 coord = c;
70 8816 }
71
72 bool NEWOUTOFBOUNDS(zfix x, zfix y, zfix z)
73 {
74 return
75 (
76 (((int32_t)y) > FFCore.enemy_removal_point[spriteremovalY2])
77 || (((int32_t)y) < FFCore.enemy_removal_point[spriteremovalY1])
78 || (((int32_t)x) < FFCore.enemy_removal_point[spriteremovalX1])
79 || (((int32_t)x) > FFCore.enemy_removal_point[spriteremovalX2])
80 || (((int32_t)z) < FFCore.enemy_removal_point[spriteremovalZ1])
81 || (((int32_t)z) > FFCore.enemy_removal_point[spriteremovalZ2])
82 );
83 }
84
85 namespace
86 {
87 int32_t trapConstantHorizontalID;
88 int32_t trapConstantVerticalID;
89 int32_t trapLOSHorizontalID;
90 int32_t trapLOSVerticalID;
91 int32_t trapLOS4WayID;
92
93 int32_t cornerTrapID;
94 int32_t centerTrapID;
95
96 int32_t rockID;
97 int32_t zoraID;
98 int32_t statueID;
99 }
100
101 18 void identifyCFEnemies()
102 {
103 18 trapConstantHorizontalID=-1;
104 18 trapConstantVerticalID=-1;
105 18 trapLOSHorizontalID=-1;
106 18 trapLOSVerticalID=-1;
107 18 trapLOS4WayID=-1;
108 18 cornerTrapID=-1;
109 18 centerTrapID=-1;
110 18 rockID=-1;
111 18 zoraID=-1;
112 18 statueID=-1;
113
114
2/2
✓ Branch 0 taken 9216 times.
✓ Branch 1 taken 18 times.
9234 for(int32_t i=0; i<eMAXGUYS; i++)
115 {
116
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trph) && trapLOSHorizontalID==-1)
117 18 trapLOSHorizontalID=i;
118
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trpv) && trapLOSVerticalID==-1)
119 18 trapLOSVerticalID=i;
120
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trp4) && trapLOS4WayID==-1)
121 18 trapLOS4WayID=i;
122
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trplr) && trapConstantHorizontalID==-1)
123 18 trapConstantHorizontalID=i;
124
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&cmbflag_trpud) && trapConstantVerticalID==-1)
125 18 trapConstantVerticalID=i;
126
127
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&eneflag_trap) && cornerTrapID==-1)
128 18 cornerTrapID=i;
129
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&eneflag_trp2) && centerTrapID==-1)
130 18 centerTrapID=i;
131
132
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&eneflag_rock) && rockID==-1)
133 18 rockID=i;
134
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 9198 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2&eneflag_zora) && zoraID==-1)
135 18 zoraID=i;
136
137
4/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 9195 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 18 times.
9216 if((guysbuf[i].flags2 & eneflag_fire) && statueID==-1)
138 18 statueID=i;
139 9216 }
140 18 }
141
142 int32_t random_layer_enemy()
143 {
144 int32_t cnt=count_layer_enemies();
145
146 if(cnt==0)
147 {
148 return eNONE;
149 }
150
151 int32_t ret=zc_oldrand()%cnt;
152 cnt=0;
153
154 for(int32_t i=0; i<6; ++i)
155 {
156 if(tmpscr->layermap[i]!=0)
157 {
158 mapscr *layerscreen=&TheMaps[(tmpscr->layermap[i]-1)*MAPSCRS]+tmpscr->layerscreen[i];
159
160 for(int32_t j=0; j<10; ++j)
161 {
162 if(layerscreen->enemy[j]>0&&layerscreen->enemy[j]<MAXGUYS)
163 {
164 if(cnt==ret)
165 {
166 return layerscreen->enemy[j];
167 }
168
169 ++cnt;
170 }
171 }
172 }
173 }
174
175 return eNONE;
176 }
177
178 int32_t count_layer_enemies()
179 {
180 int32_t cnt=0;
181
182 for(int32_t i=0; i<6; ++i)
183 {
184 if(tmpscr->layermap[i]!=0)
185 {
186 mapscr *layerscreen=&TheMaps[(tmpscr->layermap[i]-1)*MAPSCRS]+tmpscr->layerscreen[i];
187
188 for(int32_t j=0; j<10; ++j)
189 {
190 if(layerscreen->enemy[j]!=0)
191 {
192 ++cnt;
193 }
194 }
195 }
196 }
197
198 return cnt;
199 }
200
201 1427 int32_t hero_on_wall()
202 {
203 1427 zfix lx = Hero.getX();
204 1427 zfix ly = Hero.getY();
205
206
207 //zprint2("hero_on_wall x is: %d\n", lx);
208 //zprint2("hero_on_wall y is: %d\n", ly);
209
210
4/4
✓ Branch 0 taken 1341 times.
✓ Branch 1 taken 86 times.
✓ Branch 2 taken 159 times.
✓ Branch 3 taken 1182 times.
1427 if(lx>=48 && lx<=192)
211 {
212
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1179 times.
1182 if(ly==32) return up+1;
213
214
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1178 times.
1179 if(ly==128) return down+1;
215 1178 }
216
217
4/4
✓ Branch 0 taken 1346 times.
✓ Branch 1 taken 77 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1269 times.
1423 if(ly>=48 && ly<=112)
218 {
219
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1265 times.
1269 if(lx==32) return left+1;
220
221
2/2
✓ Branch 0 taken 1260 times.
✓ Branch 1 taken 5 times.
1265 if(lx==208) return right+1;
222 1260 }
223
224 1414 return 0;
225 1427 }
226
227 16625 bool tooclose(int32_t x,int32_t y,int32_t d)
228 {
229
2/2
✓ Branch 0 taken 12747 times.
✓ Branch 1 taken 3878 times.
16625 return (abs(int32_t(HeroX())-x)<d && abs(int32_t(HeroY())-y)<d);
230 }
231
232 23060 bool enemy::overpit(enemy *e)
233 {
234
2/2
✓ Branch 0 taken 23060 times.
✓ Branch 1 taken 276720 times.
299780 for ( int32_t q = 0; q < hxsz; ++q )
235 {
236
2/2
✓ Branch 0 taken 2213760 times.
✓ Branch 1 taken 276720 times.
2490480 for ( int32_t q = 0; q < hysz; ++q )
237 {
238 //check every pixel of the hitbox
239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2213760 times.
2213760 if ( ispitfall(x+q+hxofs, y+q+hyofs) )
240 {
241 //if the hitbox is over a pit, we can't land
242 return true;
243 }
244 2213760 }
245 276720 }
246 23060 return false;
247 23060 }
248
249 92966 bool enemy::shadow_overpit(enemy *e)
250 {
251
2/2
✓ Branch 0 taken 92966 times.
✓ Branch 1 taken 1456184 times.
1549150 for ( int32_t q = 0; q < hxsz; ++q )
252 {
253
2/2
✓ Branch 0 taken 22644752 times.
✓ Branch 1 taken 1456184 times.
24100936 for ( int32_t q = 0; q < hysz; ++q )
254 {
255 //check every pixel of the hitbox
256
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22644752 times.
22644752 if ( ispitfall(x+q+hxofs, y+q+hyofs+hysz-2) )
257 {
258 //if the hitbox is over a pit, we can't land
259 return true;
260 }
261 22644752 }
262 1456184 }
263 92966 return false;
264 92966 }
265
266 // Returns true iff a combo type or flag precludes enemy movement.
267 54898 bool enemy::groundblocked(int32_t dx, int32_t dy, bool isKB)
268 {
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54898 times.
54898 if(moveflags & FLAG_IGNORE_BLOCKFLAGS) return false;
270 54898 int32_t c = COMBOTYPE(dx,dy);
271
3/4
✓ Branch 0 taken 28274 times.
✓ Branch 1 taken 26624 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 26624 times.
81522 bool pit_blocks = (!(moveflags & (FLAG_CAN_PITWALK|FLAG_ONLY_PITWALK)) && (!(moveflags & FLAG_CAN_PITFALL) || !isKB));
272
3/6
✓ Branch 0 taken 26624 times.
✓ Branch 1 taken 28274 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 26624 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
54898 bool water_blocks = (!(moveflags & (FLAG_CAN_WATERWALK|FLAG_ONLY_WATERWALK|FLAG_ONLY_SHALLOW_WATERWALK)) && (!(moveflags & FLAG_CAN_WATERDROWN) || !isKB) && get_bit(quest_rules,qr_DROWN));
273
4/6
✓ Branch 0 taken 26658 times.
✓ Branch 1 taken 28240 times.
✓ Branch 2 taken 26658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 26658 times.
✗ Branch 5 not taken.
109796 return c==cPIT || c==cPITB || c==cPITC ||
274
4/6
✓ Branch 0 taken 26658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14120 times.
✓ Branch 5 taken 12538 times.
26658 c==cPITD || c==cPITR || (pit_blocks && ispitfall(dx,dy)) ||
275 // Block enemies type and block enemies flags
276
2/2
✓ Branch 0 taken 26658 times.
✓ Branch 1 taken 14120 times.
12538 combo_class_buf[c].block_enemies&1 ||
277
2/4
✓ Branch 0 taken 26658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26658 times.
✗ Branch 3 not taken.
26658 MAPFLAG(dx,dy)==mfNOENEMY || MAPCOMBOFLAG(dx,dy)==mfNOENEMY ||
278
2/4
✓ Branch 0 taken 26658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26658 times.
✗ Branch 3 not taken.
26658 MAPFLAG(dx,dy)==mfNOGROUNDENEMY || MAPCOMBOFLAG(dx,dy)==mfNOGROUNDENEMY ||
279 // Check for ladder-only combos which aren't dried water
280
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 26608 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
53316 (combo_class_buf[c].ladder_pass&1 && !iswater_type(c)) ||
281 // Check for drownable water
282
4/4
✓ Branch 0 taken 21106 times.
✓ Branch 1 taken 5552 times.
✓ Branch 2 taken 12720 times.
✓ Branch 3 taken 8386 times.
26658 (water_blocks && !(isSideViewGravity()) && (iswaterex(MAPCOMBO(dx,dy), currmap, currscr, -1, dx, dy, false, false, true, false, false)));
283 26658 }
284
285 // Returns true iff enemy is floating and blocked by a combo type or flag.
286 46484 bool enemy::flyerblocked(int32_t dx, int32_t dy, int32_t special, bool isKB)
287 {
288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46484 times.
46484 if(moveflags & FLAG_IGNORE_BLOCKFLAGS) return false;
289
3/4
✓ Branch 0 taken 41293 times.
✓ Branch 1 taken 5191 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5191 times.
51675 bool pit_blocks = (!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL) || !isKB));
290
3/4
✓ Branch 0 taken 41293 times.
✓ Branch 1 taken 5191 times.
✓ Branch 2 taken 5191 times.
✗ Branch 3 not taken.
51675 bool water_blocks = (!(moveflags & FLAG_CAN_WATERWALK) && (!(moveflags & FLAG_CAN_WATERDROWN) || !isKB));
291
2/2
✓ Branch 0 taken 5208 times.
✓ Branch 1 taken 41276 times.
87760 return ((special==spw_floater)&&
292
2/2
✓ Branch 0 taken 41224 times.
✓ Branch 1 taken 52 times.
41276 ((COMBOTYPE(dx,dy)==cNOFLYZONE)||
293
1/2
✓ Branch 0 taken 41224 times.
✗ Branch 1 not taken.
41224 (combo_class_buf[COMBOTYPE(dx,dy)].block_enemies&4)||
294
1/2
✓ Branch 0 taken 41224 times.
✗ Branch 1 not taken.
41224 (MAPFLAG(dx,dy)==mfNOENEMY)||
295
1/2
✓ Branch 0 taken 41224 times.
✗ Branch 1 not taken.
41224 (MAPCOMBOFLAG(dx,dy)==mfNOENEMY)||
296
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 41224 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
82448 (water_blocks && iswaterex(MAPCOMBO(dx, dy), currmap, currscr, -1, dx,dy, false, false, true)) ||
297
1/2
✓ Branch 0 taken 41224 times.
✗ Branch 1 not taken.
41224 (pit_blocks && ispitfall(dx,dy))));
298 46484 }
299 // Returns true iff a combo type or flag precludes enemy movement.
300 7223 bool groundblocked(int32_t dx, int32_t dy, guydata const& gd)
301 {
302 7223 int32_t c = COMBOTYPE(dx,dy);
303 7223 bool pit_blocks = !(gd.moveflags & FLAG_CAN_PITWALK);
304
2/2
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 6739 times.
7223 bool water_blocks = !(gd.moveflags & FLAG_CAN_WATERWALK) && get_bit(quest_rules,qr_DROWN);
305
3/6
✓ Branch 0 taken 7223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7223 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7223 times.
✗ Branch 5 not taken.
27924 return c==cPIT || c==cPITB || c==cPITC ||
306
4/6
✓ Branch 0 taken 7223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7223 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6739 times.
✓ Branch 5 taken 484 times.
7223 c==cPITD || c==cPITR || (pit_blocks && ispitfall(dx,dy)) ||
307 // Block enemies type and block enemies flags
308
2/2
✓ Branch 0 taken 7223 times.
✓ Branch 1 taken 6739 times.
484 combo_class_buf[c].block_enemies&1 ||
309
2/4
✓ Branch 0 taken 7223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7223 times.
✗ Branch 3 not taken.
7223 MAPFLAG(dx,dy)==mfNOENEMY || MAPCOMBOFLAG(dx,dy)==mfNOENEMY ||
310
2/4
✓ Branch 0 taken 7223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7223 times.
✗ Branch 3 not taken.
7223 MAPFLAG(dx,dy)==mfNOGROUNDENEMY || MAPCOMBOFLAG(dx,dy)==mfNOGROUNDENEMY ||
311 // Check for ladder-only combos which aren't dried water
312
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7219 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
14446 (combo_class_buf[c].ladder_pass&1 && !iswater_type(c)) ||
313 // Check for drownable water
314
4/4
✓ Branch 0 taken 1176 times.
✓ Branch 1 taken 6047 times.
✓ Branch 2 taken 1134 times.
✓ Branch 3 taken 42 times.
7223 (water_blocks && !(isSideViewGravity()) && (iswaterex(MAPCOMBO(dx,dy), currmap, currscr, -1, dx, dy, false, false, true)));
315 }
316
317 // Returns true iff enemy is floating and blocked by a combo type or flag.
318 2517 bool flyerblocked(int32_t dx, int32_t dy, int32_t special, guydata const& gd)
319 {
320
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 bool pit_blocks = (!(gd.moveflags & FLAG_CAN_PITWALK) && !(gd.moveflags & FLAG_CAN_PITFALL));
321 2517 bool water_blocks = !(gd.moveflags & FLAG_CAN_WATERWALK);
322
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2517 times.
5034 return ((special==spw_floater)&&
323
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 ((COMBOTYPE(dx,dy)==cNOFLYZONE)||
324
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (combo_class_buf[COMBOTYPE(dx,dy)].block_enemies&4)||
325
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (MAPFLAG(dx,dy)==mfNOENEMY)||
326
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (MAPCOMBOFLAG(dx,dy)==mfNOENEMY)||
327
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2517 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5034 (water_blocks && iswaterex(MAPCOMBO(dx,dy), currmap, currscr, -1, dx, dy, false, false, true)) ||
328
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (pit_blocks && ispitfall(dx,dy))));
329 }
330
331 /**********************************/
332 /******* Enemy Base Class *******/
333 /**********************************/
334
335 /* ROM data flags
336
337 */
338
339 eFire::eFire(eFire const & other, bool new_script_uid, bool clear_parent_script_UID):
340 //Struct Element Type Purpose
341 //sprite(other),
342 enemy(other),
343 clk4(other.clk4),
344 shield(other.shield)
345
346 {
347
348 //arrays
349
350 if(other.scrmem)
351 {
352 alloc_scriptmem();
353 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
354
355 scrmem->scriptData = other.scrmem->scriptData;
356 }
357 else scrmem = NULL;
358 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
359 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
360
361 for(int32_t i=0; i<edefLAST255; i++)
362 defense[i]=other.defense[i];
363 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
364 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
365
366 if(new_script_uid)
367 {
368 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
369 }
370 if(clear_parent_script_UID)
371 {
372 parent_script_UID = 0;
373 }
374 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
375 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
376
377 for ( int32_t q = 0; q < 8; q++ )
378 {
379 initD[q] = other.initD[q];
380 weap_initiald[q] = other.weap_initiald[q];
381 }
382 for ( int32_t q = 0; q < 2; q++ )
383 {
384 initA[q] = other.initA[q];
385 weap_initiala[q] = other.weap_initiala[q];
386 }
387 }
388
389 eOther::eOther(eOther const & other, bool new_script_uid, bool clear_parent_script_UID):
390 //Struct Element Type Purpose
391 //sprite(other),
392 enemy(other),
393 clk4(other.clk4),
394 shield(other.shield)
395
396 {
397
398 //arrays
399
400 if(other.scrmem)
401 {
402 alloc_scriptmem();
403 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
404
405 scrmem->scriptData = other.scrmem->scriptData;
406 }
407 else scrmem = NULL;
408 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
409 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
410
411 for(int32_t i=0; i<edefLAST255; i++)
412 defense[i]=other.defense[i];
413 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
414 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
415
416 if(new_script_uid)
417 {
418 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
419 }
420 if(clear_parent_script_UID)
421 {
422 parent_script_UID = 0;
423 }
424 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
425 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
426
427 for ( int32_t q = 0; q < 8; q++ )
428 {
429 initD[q] = other.initD[q];
430 weap_initiald[q] = other.weap_initiald[q];
431 }
432 for ( int32_t q = 0; q < 2; q++ )
433 {
434 initA[q] = other.initA[q];
435 weap_initiala[q] = other.weap_initiala[q];
436 }
437 }
438
439
440
441
442 eScript::eScript(eScript const & other, bool new_script_uid, bool clear_parent_script_UID):
443 //Struct Element Type Purpose
444 //sprite(other),
445 enemy(other),
446 clk4(other.clk4),
447 shield(other.shield)
448
449 {
450
451 //arrays
452
453 if(other.scrmem)
454 {
455 alloc_scriptmem();
456 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
457
458 scrmem->scriptData = other.scrmem->scriptData;
459 }
460 else scrmem = NULL;
461 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
462 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
463
464 for(int32_t i=0; i<edefLAST255; i++)
465 defense[i]=other.defense[i];
466 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
467 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
468
469 if(new_script_uid)
470 {
471 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
472 }
473 if(clear_parent_script_UID)
474 {
475 parent_script_UID = 0;
476 }
477 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
478 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
479
480 for ( int32_t q = 0; q < 8; q++ )
481 {
482 initD[q] = other.initD[q];
483 weap_initiald[q] = other.weap_initiald[q];
484 }
485 for ( int32_t q = 0; q < 2; q++ )
486 {
487 initA[q] = other.initA[q];
488 weap_initiala[q] = other.weap_initiala[q];
489 }
490 }
491
492 eFriendly::eFriendly(eFriendly const & other, bool new_script_uid, bool clear_parent_script_UID):
493 //Struct Element Type Purpose
494 //sprite(other),
495 enemy(other),
496 clk4(other.clk4),
497 shield(other.shield)
498
499 {
500
501 //arrays
502
503 if(other.scrmem)
504 {
505 alloc_scriptmem();
506 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
507
508 scrmem->scriptData = other.scrmem->scriptData;
509 }
510 else scrmem = NULL;
511 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
512 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
513
514 for(int32_t i=0; i<edefLAST255; i++)
515 defense[i]=other.defense[i];
516 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
517 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
518
519 if(new_script_uid)
520 {
521 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
522 }
523 if(clear_parent_script_UID)
524 {
525 parent_script_UID = 0;
526 }
527 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
528 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
529
530 for ( int32_t q = 0; q < 8; q++ )
531 {
532 initD[q] = other.initD[q];
533 weap_initiald[q] = other.weap_initiald[q];
534 }
535 for ( int32_t q = 0; q < 2; q++ )
536 {
537 initA[q] = other.initA[q];
538 weap_initiala[q] = other.weap_initiala[q];
539 }
540 }
541
542 eGhini::eGhini(eGhini const & other, bool new_script_uid, bool clear_parent_script_UID):
543 //Struct Element Type Purpose
544 //sprite(other),
545 enemy(other),
546 clk4(other.clk4),
547 ox(other.ox),
548 oy(other.oy),
549 c(other.c)
550
551 {
552
553 //arrays
554
555 if(other.scrmem)
556 {
557 alloc_scriptmem();
558 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
559
560 scrmem->scriptData = other.scrmem->scriptData;
561 }
562 else scrmem = NULL;
563 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
564 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
565
566 for(int32_t i=0; i<edefLAST255; i++)
567 defense[i]=other.defense[i];
568 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
569 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
570
571 if(new_script_uid)
572 {
573 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
574 }
575 if(clear_parent_script_UID)
576 {
577 parent_script_UID = 0;
578 }
579 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
580 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
581
582 for ( int32_t q = 0; q < 8; q++ )
583 {
584 initD[q] = other.initD[q];
585 weap_initiald[q] = other.weap_initiald[q];
586 }
587 for ( int32_t q = 0; q < 2; q++ )
588 {
589 initA[q] = other.initA[q];
590 weap_initiala[q] = other.weap_initiala[q];
591 }
592 }
593
594 eTektite::eTektite(eTektite const & other, bool new_script_uid, bool clear_parent_script_UID):
595 //Struct Element Type Purpose
596 //sprite(other),
597 enemy(other),
598 old_y(other.old_y),
599 clk2start(other.clk2start),
600 cstart(other.cstart),
601 c(other.c)
602
603 {
604
605 //arrays
606
607 if(other.scrmem)
608 {
609 alloc_scriptmem();
610 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
611
612 scrmem->scriptData = other.scrmem->scriptData;
613 }
614 else scrmem = NULL;
615 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
616 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
617
618 for(int32_t i=0; i<edefLAST255; i++)
619 defense[i]=other.defense[i];
620 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
621 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
622
623 if(new_script_uid)
624 {
625 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
626 }
627 if(clear_parent_script_UID)
628 {
629 parent_script_UID = 0;
630 }
631 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
632 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
633
634 for ( int32_t q = 0; q < 8; q++ )
635 {
636 initD[q] = other.initD[q];
637 weap_initiald[q] = other.weap_initiald[q];
638 }
639 for ( int32_t q = 0; q < 2; q++ )
640 {
641 initA[q] = other.initA[q];
642 weap_initiala[q] = other.weap_initiala[q];
643 }
644 }
645
646 eItemFairy::eItemFairy(eItemFairy const & other, bool new_script_uid, bool clear_parent_script_UID):
647 //Struct Element Type Purpose
648 //sprite(other),
649 enemy(other)
650 {
651
652 //arrays
653
654 if(other.scrmem)
655 {
656 alloc_scriptmem();
657 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
658
659 scrmem->scriptData = other.scrmem->scriptData;
660 }
661 else scrmem = NULL;
662 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
663 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
664
665 for(int32_t i=0; i<edefLAST255; i++)
666 defense[i]=other.defense[i];
667 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
668 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
669
670 if(new_script_uid)
671 {
672 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
673 }
674 if(clear_parent_script_UID)
675 {
676 parent_script_UID = 0;
677 }
678 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
679 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
680
681 for ( int32_t q = 0; q < 8; q++ )
682 {
683 initD[q] = other.initD[q];
684 weap_initiald[q] = other.weap_initiald[q];
685 }
686 for ( int32_t q = 0; q < 2; q++ )
687 {
688 initA[q] = other.initA[q];
689 weap_initiala[q] = other.weap_initiala[q];
690 }
691 }
692
693 ePeahat::ePeahat(ePeahat const & other, bool new_script_uid, bool clear_parent_script_UID):
694 //Struct Element Type Purpose
695 //sprite(other),
696 enemy(other),
697 ox(other.ox),
698 oy(other.oy),
699 c(other.c)
700 {
701
702 //arrays
703
704 if(other.scrmem)
705 {
706 alloc_scriptmem();
707 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
708
709 scrmem->scriptData = other.scrmem->scriptData;
710 }
711 else scrmem = NULL;
712 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
713 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
714
715 for(int32_t i=0; i<edefLAST255; i++)
716 defense[i]=other.defense[i];
717 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
718 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
719
720 if(new_script_uid)
721 {
722 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
723 }
724 if(clear_parent_script_UID)
725 {
726 parent_script_UID = 0;
727 }
728 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
729 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
730
731 for ( int32_t q = 0; q < 8; q++ )
732 {
733 initD[q] = other.initD[q];
734 weap_initiald[q] = other.weap_initiald[q];
735 }
736 for ( int32_t q = 0; q < 2; q++ )
737 {
738 initA[q] = other.initA[q];
739 weap_initiala[q] = other.weap_initiala[q];
740 }
741 }
742
743 eLeever::eLeever(eLeever const & other, bool new_script_uid, bool clear_parent_script_UID):
744 //Struct Element Type Purpose
745 //sprite(other),
746 enemy(other),
747 temprule(other.temprule)
748 {
749
750 //arrays
751
752 if(other.scrmem)
753 {
754 alloc_scriptmem();
755 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
756
757 scrmem->scriptData = other.scrmem->scriptData;
758 }
759 else scrmem = NULL;
760 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
761 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
762
763 for(int32_t i=0; i<edefLAST255; i++)
764 defense[i]=other.defense[i];
765 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
766 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
767
768 if(new_script_uid)
769 {
770 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
771 }
772 if(clear_parent_script_UID)
773 {
774 parent_script_UID = 0;
775 }
776 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
777 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
778
779 for ( int32_t q = 0; q < 8; q++ )
780 {
781 initD[q] = other.initD[q];
782 weap_initiald[q] = other.weap_initiald[q];
783 }
784 for ( int32_t q = 0; q < 2; q++ )
785 {
786 initA[q] = other.initA[q];
787 weap_initiala[q] = other.weap_initiala[q];
788 }
789 }
790
791 eWallM::eWallM(eWallM const & other, bool new_script_uid, bool clear_parent_script_UID):
792 //Struct Element Type Purpose
793 //sprite(other),
794 enemy(other)
795 {
796
797 //arrays
798
799 if(other.scrmem)
800 {
801 alloc_scriptmem();
802 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
803
804 scrmem->scriptData = other.scrmem->scriptData;
805 }
806 else scrmem = NULL;
807 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
808 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
809
810 for(int32_t i=0; i<edefLAST255; i++)
811 defense[i]=other.defense[i];
812 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
813 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
814
815 if(new_script_uid)
816 {
817 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
818 }
819 if(clear_parent_script_UID)
820 {
821 parent_script_UID = 0;
822 }
823 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
824 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
825
826 for ( int32_t q = 0; q < 8; q++ )
827 {
828 initD[q] = other.initD[q];
829 weap_initiald[q] = other.weap_initiald[q];
830 }
831 for ( int32_t q = 0; q < 2; q++ )
832 {
833 initA[q] = other.initA[q];
834 weap_initiala[q] = other.weap_initiala[q];
835 }
836 }
837
838 eStalfos::eStalfos(eStalfos const & other, bool new_script_uid, bool clear_parent_script_UID):
839 //Struct Element Type Purpose
840 //sprite(other),
841 enemy(other),
842 clk4(other.clk4),
843 clk5(other.clk5),
844 fired(other.fired),
845 shield(other.shield),
846 dashing(other.dashing),
847 multishot(other.multishot),
848 fy(other.fy),
849 shadowdistance(other.shadowdistance)
850 {
851
852 //arrays
853
854 if(other.scrmem)
855 {
856 alloc_scriptmem();
857 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
858
859 scrmem->scriptData = other.scrmem->scriptData;
860 }
861 else scrmem = NULL;
862 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
863 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
864
865 for(int32_t i=0; i<edefLAST255; i++)
866 defense[i]=other.defense[i];
867 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
868 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
869
870 if(new_script_uid)
871 {
872 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
873 }
874 if(clear_parent_script_UID)
875 {
876 parent_script_UID = 0;
877 }
878 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
879 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
880
881 for ( int32_t q = 0; q < 8; q++ )
882 {
883 initD[q] = other.initD[q];
884 weap_initiald[q] = other.weap_initiald[q];
885 }
886 for ( int32_t q = 0; q < 2; q++ )
887 {
888 initA[q] = other.initA[q];
889 weap_initiala[q] = other.weap_initiala[q];
890 }
891 }
892
893 eZora::eZora(eZora const & other, bool new_script_uid, bool clear_parent_script_UID):
894 //Struct Element Type Purpose
895 //sprite(other),
896 enemy(other)
897 {
898
899 //arrays
900
901 if(other.scrmem)
902 {
903 alloc_scriptmem();
904 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
905
906 scrmem->scriptData = other.scrmem->scriptData;
907 }
908 else scrmem = NULL;
909 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
910 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
911
912 for(int32_t i=0; i<edefLAST255; i++)
913 defense[i]=other.defense[i];
914 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
915 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
916
917 if(new_script_uid)
918 {
919 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
920 }
921 if(clear_parent_script_UID)
922 {
923 parent_script_UID = 0;
924 }
925 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
926 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
927
928 for ( int32_t q = 0; q < 8; q++ )
929 {
930 initD[q] = other.initD[q];
931 weap_initiald[q] = other.weap_initiald[q];
932 }
933 for ( int32_t q = 0; q < 2; q++ )
934 {
935 initA[q] = other.initA[q];
936 weap_initiala[q] = other.weap_initiala[q];
937 }
938 }
939
940 eSpinTile::eSpinTile(eSpinTile const & other, bool new_script_uid, bool clear_parent_script_UID):
941 //Struct Element Type Purpose
942 //sprite(other),
943 enemy(other)
944 {
945
946 //arrays
947
948 if(other.scrmem)
949 {
950 alloc_scriptmem();
951 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
952
953 scrmem->scriptData = other.scrmem->scriptData;
954 }
955 else scrmem = NULL;
956 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
957 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
958
959 for(int32_t i=0; i<edefLAST255; i++)
960 defense[i]=other.defense[i];
961 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
962 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
963
964 if(new_script_uid)
965 {
966 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
967 }
968 if(clear_parent_script_UID)
969 {
970 parent_script_UID = 0;
971 }
972 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
973 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
974
975 for ( int32_t q = 0; q < 8; q++ )
976 {
977 initD[q] = other.initD[q];
978 weap_initiald[q] = other.weap_initiald[q];
979 }
980 for ( int32_t q = 0; q < 2; q++ )
981 {
982 initA[q] = other.initA[q];
983 weap_initiala[q] = other.weap_initiala[q];
984 }
985 }
986
987 eNPC::eNPC(eNPC const & other, bool new_script_uid, bool clear_parent_script_UID):
988 //Struct Element Type Purpose
989 //sprite(other),
990 enemy(other)
991 {
992
993 //arrays
994
995 if(other.scrmem)
996 {
997 alloc_scriptmem();
998 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
999
1000 scrmem->scriptData = other.scrmem->scriptData;
1001 }
1002 else scrmem = NULL;
1003 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1004 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1005
1006 for(int32_t i=0; i<edefLAST255; i++)
1007 defense[i]=other.defense[i];
1008 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1009 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1010
1011 if(new_script_uid)
1012 {
1013 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1014 }
1015 if(clear_parent_script_UID)
1016 {
1017 parent_script_UID = 0;
1018 }
1019 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1020 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1021
1022 for ( int32_t q = 0; q < 8; q++ )
1023 {
1024 initD[q] = other.initD[q];
1025 weap_initiald[q] = other.weap_initiald[q];
1026 }
1027 for ( int32_t q = 0; q < 2; q++ )
1028 {
1029 initA[q] = other.initA[q];
1030 weap_initiala[q] = other.weap_initiala[q];
1031 }
1032 }
1033
1034 eTrigger::eTrigger(eTrigger const & other, bool new_script_uid, bool clear_parent_script_UID):
1035 //Struct Element Type Purpose
1036 //sprite(other),
1037 enemy(other)
1038 {
1039
1040 //arrays
1041
1042 if(other.scrmem)
1043 {
1044 alloc_scriptmem();
1045 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1046
1047 scrmem->scriptData = other.scrmem->scriptData;
1048 }
1049 else scrmem = NULL;
1050 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1051 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1052
1053 for(int32_t i=0; i<edefLAST255; i++)
1054 defense[i]=other.defense[i];
1055 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1056 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1057
1058 if(new_script_uid)
1059 {
1060 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1061 }
1062 if(clear_parent_script_UID)
1063 {
1064 parent_script_UID = 0;
1065 }
1066 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1067 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1068
1069 for ( int32_t q = 0; q < 8; q++ )
1070 {
1071 initD[q] = other.initD[q];
1072 weap_initiald[q] = other.weap_initiald[q];
1073 }
1074 for ( int32_t q = 0; q < 2; q++ )
1075 {
1076 initA[q] = other.initA[q];
1077 weap_initiala[q] = other.weap_initiala[q];
1078 }
1079 }
1080
1081 eProjectile::eProjectile(eProjectile const & other, bool new_script_uid, bool clear_parent_script_UID):
1082 //Struct Element Type Purpose
1083 //sprite(other),
1084 enemy(other),
1085 minRange(other.minRange)
1086 {
1087
1088 //arrays
1089
1090 if(other.scrmem)
1091 {
1092 alloc_scriptmem();
1093 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1094
1095 scrmem->scriptData = other.scrmem->scriptData;
1096 }
1097 else scrmem = NULL;
1098 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1099 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1100
1101 for(int32_t i=0; i<edefLAST255; i++)
1102 defense[i]=other.defense[i];
1103 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1104 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1105
1106 if(new_script_uid)
1107 {
1108 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1109 }
1110 if(clear_parent_script_UID)
1111 {
1112 parent_script_UID = 0;
1113 }
1114 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1115 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1116
1117 for ( int32_t q = 0; q < 8; q++ )
1118 {
1119 initD[q] = other.initD[q];
1120 weap_initiald[q] = other.weap_initiald[q];
1121 }
1122 for ( int32_t q = 0; q < 2; q++ )
1123 {
1124 initA[q] = other.initA[q];
1125 weap_initiala[q] = other.weap_initiala[q];
1126 }
1127 }
1128
1129 eBoulder::eBoulder(eBoulder const & other, bool new_script_uid, bool clear_parent_script_UID):
1130 //Struct Element Type Purpose
1131 //sprite(other),
1132 enemy(other)
1133 {
1134
1135 //arrays
1136
1137 if(other.scrmem)
1138 {
1139 alloc_scriptmem();
1140 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1141
1142 scrmem->scriptData = other.scrmem->scriptData;
1143 }
1144 else scrmem = NULL;
1145 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1146 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1147
1148 for(int32_t i=0; i<edefLAST255; i++)
1149 defense[i]=other.defense[i];
1150 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1151 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1152
1153 if(new_script_uid)
1154 {
1155 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1156 }
1157 if(clear_parent_script_UID)
1158 {
1159 parent_script_UID = 0;
1160 }
1161 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1162 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1163
1164 for ( int32_t q = 0; q < 8; q++ )
1165 {
1166 initD[q] = other.initD[q];
1167 weap_initiald[q] = other.weap_initiald[q];
1168 }
1169 for ( int32_t q = 0; q < 2; q++ )
1170 {
1171 initA[q] = other.initA[q];
1172 weap_initiala[q] = other.weap_initiala[q];
1173 }
1174 }
1175
1176 eRock::eRock(eRock const & other, bool new_script_uid, bool clear_parent_script_UID):
1177 //Struct Element Type Purpose
1178 //sprite(other),
1179 enemy(other)
1180 {
1181
1182 //arrays
1183
1184 if(other.scrmem)
1185 {
1186 alloc_scriptmem();
1187 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1188
1189 scrmem->scriptData = other.scrmem->scriptData;
1190 }
1191 else scrmem = NULL;
1192 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1193 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1194
1195 for(int32_t i=0; i<edefLAST255; i++)
1196 defense[i]=other.defense[i];
1197 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1198 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1199
1200 if(new_script_uid)
1201 {
1202 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1203 }
1204 if(clear_parent_script_UID)
1205 {
1206 parent_script_UID = 0;
1207 }
1208 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1209 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1210
1211 for ( int32_t q = 0; q < 8; q++ )
1212 {
1213 initD[q] = other.initD[q];
1214 weap_initiald[q] = other.weap_initiald[q];
1215 }
1216 for ( int32_t q = 0; q < 2; q++ )
1217 {
1218 initA[q] = other.initA[q];
1219 weap_initiala[q] = other.weap_initiala[q];
1220 }
1221 }
1222
1223 eTrap2::eTrap2(eTrap2 const & other, bool new_script_uid, bool clear_parent_script_UID):
1224 //Struct Element Type Purpose
1225 //sprite(other),
1226 enemy(other)
1227 {
1228
1229 //arrays
1230
1231 if(other.scrmem)
1232 {
1233 alloc_scriptmem();
1234 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1235
1236 scrmem->scriptData = other.scrmem->scriptData;
1237 }
1238 else scrmem = NULL;
1239 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1240 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1241
1242 for(int32_t i=0; i<edefLAST255; i++)
1243 defense[i]=other.defense[i];
1244 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1245 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1246
1247 if(new_script_uid)
1248 {
1249 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1250 }
1251 if(clear_parent_script_UID)
1252 {
1253 parent_script_UID = 0;
1254 }
1255 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1256 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1257
1258 for ( int32_t q = 0; q < 8; q++ )
1259 {
1260 initD[q] = other.initD[q];
1261 weap_initiald[q] = other.weap_initiald[q];
1262 }
1263 for ( int32_t q = 0; q < 2; q++ )
1264 {
1265 initA[q] = other.initA[q];
1266 weap_initiala[q] = other.weap_initiala[q];
1267 }
1268 }
1269
1270 eTrap::eTrap(eTrap const & other, bool new_script_uid, bool clear_parent_script_UID):
1271 //Struct Element Type Purpose
1272 //sprite(other),
1273 enemy(other),
1274 ox(other.ox),
1275 oy(other.oy)
1276 {
1277
1278 //arrays
1279
1280 if(other.scrmem)
1281 {
1282 alloc_scriptmem();
1283 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1284
1285 scrmem->scriptData = other.scrmem->scriptData;
1286 }
1287 else scrmem = NULL;
1288 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1289 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1290
1291 for(int32_t i=0; i<edefLAST255; i++)
1292 defense[i]=other.defense[i];
1293 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1294 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1295
1296 if(new_script_uid)
1297 {
1298 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1299 }
1300 if(clear_parent_script_UID)
1301 {
1302 parent_script_UID = 0;
1303 }
1304 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1305 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1306
1307 for ( int32_t q = 0; q < 8; q++ )
1308 {
1309 initD[q] = other.initD[q];
1310 weap_initiald[q] = other.weap_initiald[q];
1311 }
1312 for ( int32_t q = 0; q < 2; q++ )
1313 {
1314 initA[q] = other.initA[q];
1315 weap_initiala[q] = other.weap_initiala[q];
1316 }
1317 }
1318
1319
1320
1321
1322 eKeese::eKeese(eKeese const & other, bool new_script_uid, bool clear_parent_script_UID):
1323 //Struct Element Type Purpose
1324 //sprite(other),
1325 enemy(other),
1326 ox(other.ox),
1327 c(other.c),
1328 clk4(other.clk4),
1329 oy(other.oy)
1330 {
1331
1332 //arrays
1333
1334 if(other.scrmem)
1335 {
1336 alloc_scriptmem();
1337 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1338
1339 scrmem->scriptData = other.scrmem->scriptData;
1340 }
1341 else scrmem = NULL;
1342 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1343 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1344
1345 for(int32_t i=0; i<edefLAST255; i++)
1346 defense[i]=other.defense[i];
1347 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1348 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1349
1350 if(new_script_uid)
1351 {
1352 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1353 }
1354 if(clear_parent_script_UID)
1355 {
1356 parent_script_UID = 0;
1357 }
1358 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1359 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1360
1361 for ( int32_t q = 0; q < 8; q++ )
1362 {
1363 initD[q] = other.initD[q];
1364 weap_initiald[q] = other.weap_initiald[q];
1365 }
1366 for ( int32_t q = 0; q < 2; q++ )
1367 {
1368 initA[q] = other.initA[q];
1369 weap_initiala[q] = other.weap_initiala[q];
1370 }
1371 }
1372
1373 eWizzrobe::eWizzrobe(eWizzrobe const & other, bool new_script_uid, bool clear_parent_script_UID):
1374 //Struct Element Type Purpose
1375 //sprite(other),
1376 enemy(other),
1377 charging(other.charging),
1378 firing(other.firing),
1379 fclk(other.fclk)
1380 {
1381
1382 //arrays
1383
1384 if(other.scrmem)
1385 {
1386 alloc_scriptmem();
1387 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1388
1389 scrmem->scriptData = other.scrmem->scriptData;
1390 }
1391 else scrmem = NULL;
1392 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1393 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1394
1395 for(int32_t i=0; i<edefLAST255; i++)
1396 defense[i]=other.defense[i];
1397 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1398 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1399
1400 if(new_script_uid)
1401 {
1402 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1403 }
1404 if(clear_parent_script_UID)
1405 {
1406 parent_script_UID = 0;
1407 }
1408 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1409 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1410
1411 for ( int32_t q = 0; q < 8; q++ )
1412 {
1413 initD[q] = other.initD[q];
1414 weap_initiald[q] = other.weap_initiald[q];
1415 }
1416 for ( int32_t q = 0; q < 2; q++ )
1417 {
1418 initA[q] = other.initA[q];
1419 weap_initiala[q] = other.weap_initiala[q];
1420 }
1421 }
1422
1423 eDodongo::eDodongo(eDodongo const & other, bool new_script_uid, bool clear_parent_script_UID):
1424 //Struct Element Type Purpose
1425 //sprite(other),
1426 enemy(other)
1427 {
1428
1429 //arrays
1430
1431 if(other.scrmem)
1432 {
1433 alloc_scriptmem();
1434 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1435
1436 scrmem->scriptData = other.scrmem->scriptData;
1437 }
1438 else scrmem = NULL;
1439 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1440 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1441
1442 for(int32_t i=0; i<edefLAST255; i++)
1443 defense[i]=other.defense[i];
1444 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1445 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1446
1447 if(new_script_uid)
1448 {
1449 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1450 }
1451 if(clear_parent_script_UID)
1452 {
1453 parent_script_UID = 0;
1454 }
1455 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1456 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1457
1458 for ( int32_t q = 0; q < 8; q++ )
1459 {
1460 initD[q] = other.initD[q];
1461 weap_initiald[q] = other.weap_initiald[q];
1462 }
1463 for ( int32_t q = 0; q < 2; q++ )
1464 {
1465 initA[q] = other.initA[q];
1466 weap_initiala[q] = other.weap_initiala[q];
1467 }
1468 }
1469
1470 eDodongo2::eDodongo2(eDodongo2 const & other, bool new_script_uid, bool clear_parent_script_UID):
1471 //Struct Element Type Purpose
1472 //sprite(other),
1473 enemy(other),
1474 previous_dir(other.previous_dir)
1475 {
1476
1477 //arrays
1478
1479 if(other.scrmem)
1480 {
1481 alloc_scriptmem();
1482 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1483
1484 scrmem->scriptData = other.scrmem->scriptData;
1485 }
1486 else scrmem = NULL;
1487 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1488 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1489
1490 for(int32_t i=0; i<edefLAST255; i++)
1491 defense[i]=other.defense[i];
1492 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1493 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1494
1495 if(new_script_uid)
1496 {
1497 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1498 }
1499 if(clear_parent_script_UID)
1500 {
1501 parent_script_UID = 0;
1502 }
1503 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1504 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1505
1506 for ( int32_t q = 0; q < 8; q++ )
1507 {
1508 initD[q] = other.initD[q];
1509 weap_initiald[q] = other.weap_initiald[q];
1510 }
1511 for ( int32_t q = 0; q < 2; q++ )
1512 {
1513 initA[q] = other.initA[q];
1514 weap_initiala[q] = other.weap_initiala[q];
1515 }
1516 }
1517
1518 eAquamentus::eAquamentus(eAquamentus const & other, bool new_script_uid, bool clear_parent_script_UID):
1519 //Struct Element Type Purpose
1520 //sprite(other),
1521 enemy(other),
1522 fbx(other.fbx),
1523 clk4(other.clk4)
1524 {
1525
1526 //arrays
1527
1528 if(other.scrmem)
1529 {
1530 alloc_scriptmem();
1531 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1532
1533 scrmem->scriptData = other.scrmem->scriptData;
1534 }
1535 else scrmem = NULL;
1536 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1537 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1538
1539 for(int32_t i=0; i<edefLAST255; i++)
1540 defense[i]=other.defense[i];
1541 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1542 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1543
1544 if(new_script_uid)
1545 {
1546 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1547 }
1548 if(clear_parent_script_UID)
1549 {
1550 parent_script_UID = 0;
1551 }
1552 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1553 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1554
1555 for ( int32_t q = 0; q < 8; q++ )
1556 {
1557 initD[q] = other.initD[q];
1558 weap_initiald[q] = other.weap_initiald[q];
1559 }
1560 for ( int32_t q = 0; q < 2; q++ )
1561 {
1562 initA[q] = other.initA[q];
1563 weap_initiala[q] = other.weap_initiala[q];
1564 }
1565 }
1566
1567 eGohma::eGohma(eGohma const & other, bool new_script_uid, bool clear_parent_script_UID):
1568 //Struct Element Type Purpose
1569 //sprite(other),
1570 enemy(other),
1571 clk4(other.clk4)
1572 {
1573
1574 //arrays
1575
1576 if(other.scrmem)
1577 {
1578 alloc_scriptmem();
1579 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1580
1581 scrmem->scriptData = other.scrmem->scriptData;
1582 }
1583 else scrmem = NULL;
1584 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1585 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1586
1587 for(int32_t i=0; i<edefLAST255; i++)
1588 defense[i]=other.defense[i];
1589 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1590 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1591
1592 if(new_script_uid)
1593 {
1594 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1595 }
1596 if(clear_parent_script_UID)
1597 {
1598 parent_script_UID = 0;
1599 }
1600 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1601 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1602
1603 for ( int32_t q = 0; q < 8; q++ )
1604 {
1605 initD[q] = other.initD[q];
1606 weap_initiald[q] = other.weap_initiald[q];
1607 }
1608 for ( int32_t q = 0; q < 2; q++ )
1609 {
1610 initA[q] = other.initA[q];
1611 weap_initiala[q] = other.weap_initiala[q];
1612 }
1613 }
1614
1615 eLilDig::eLilDig(eLilDig const & other, bool new_script_uid, bool clear_parent_script_UID):
1616 //Struct Element Type Purpose
1617 //sprite(other),
1618 enemy(other)
1619 {
1620
1621 //arrays
1622
1623 if(other.scrmem)
1624 {
1625 alloc_scriptmem();
1626 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1627
1628 scrmem->scriptData = other.scrmem->scriptData;
1629 }
1630 else scrmem = NULL;
1631 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1632 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1633
1634 for(int32_t i=0; i<edefLAST255; i++)
1635 defense[i]=other.defense[i];
1636 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1637 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1638
1639 if(new_script_uid)
1640 {
1641 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1642 }
1643 if(clear_parent_script_UID)
1644 {
1645 parent_script_UID = 0;
1646 }
1647 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1648 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1649
1650 for ( int32_t q = 0; q < 8; q++ )
1651 {
1652 initD[q] = other.initD[q];
1653 weap_initiald[q] = other.weap_initiald[q];
1654 }
1655 for ( int32_t q = 0; q < 2; q++ )
1656 {
1657 initA[q] = other.initA[q];
1658 weap_initiala[q] = other.weap_initiala[q];
1659 }
1660 }
1661
1662 eBigDig::eBigDig(eBigDig const & other, bool new_script_uid, bool clear_parent_script_UID):
1663 //Struct Element Type Purpose
1664 //sprite(other),
1665 enemy(other)
1666 {
1667
1668 //arrays
1669
1670 if(other.scrmem)
1671 {
1672 alloc_scriptmem();
1673 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1674
1675 scrmem->scriptData = other.scrmem->scriptData;
1676 }
1677 else scrmem = NULL;
1678 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1679 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1680
1681 for(int32_t i=0; i<edefLAST255; i++)
1682 defense[i]=other.defense[i];
1683 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1684 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1685
1686 if(new_script_uid)
1687 {
1688 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1689 }
1690 if(clear_parent_script_UID)
1691 {
1692 parent_script_UID = 0;
1693 }
1694 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1695 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1696
1697 for ( int32_t q = 0; q < 8; q++ )
1698 {
1699 initD[q] = other.initD[q];
1700 weap_initiald[q] = other.weap_initiald[q];
1701 }
1702 for ( int32_t q = 0; q < 2; q++ )
1703 {
1704 initA[q] = other.initA[q];
1705 weap_initiala[q] = other.weap_initiala[q];
1706 }
1707 }
1708
1709 eGanon::eGanon(eGanon const & other, bool new_script_uid, bool clear_parent_script_UID):
1710 //Struct Element Type Purpose
1711 //sprite(other),
1712 enemy(other),
1713 Stunclk(other.Stunclk)
1714
1715 {
1716
1717 //arrays
1718
1719 if(other.scrmem)
1720 {
1721 alloc_scriptmem();
1722 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1723
1724 scrmem->scriptData = other.scrmem->scriptData;
1725 }
1726 else scrmem = NULL;
1727 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1728 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1729
1730 for(int32_t i=0; i<edefLAST255; i++)
1731 defense[i]=other.defense[i];
1732 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1733 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1734
1735 if(new_script_uid)
1736 {
1737 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1738 }
1739 if(clear_parent_script_UID)
1740 {
1741 parent_script_UID = 0;
1742 }
1743 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1744 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1745
1746 for ( int32_t q = 0; q < 8; q++ )
1747 {
1748 initD[q] = other.initD[q];
1749 weap_initiald[q] = other.weap_initiald[q];
1750 }
1751 for ( int32_t q = 0; q < 2; q++ )
1752 {
1753 initA[q] = other.initA[q];
1754 weap_initiala[q] = other.weap_initiala[q];
1755 }
1756 }
1757
1758 eMoldorm::eMoldorm(eMoldorm const & other, bool new_script_uid, bool clear_parent_script_UID):
1759 //Struct Element Type Purpose
1760 //sprite(other),
1761 enemy(other),
1762 segcnt(other.segcnt),
1763 segid(other.segid)
1764
1765 {
1766
1767 //arrays
1768
1769 if(other.scrmem)
1770 {
1771 alloc_scriptmem();
1772 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1773
1774 scrmem->scriptData = other.scrmem->scriptData;
1775 }
1776 else scrmem = NULL;
1777 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1778 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1779
1780 for(int32_t i=0; i<edefLAST255; i++)
1781 defense[i]=other.defense[i];
1782 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1783 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1784
1785 if(new_script_uid)
1786 {
1787 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1788 }
1789 if(clear_parent_script_UID)
1790 {
1791 parent_script_UID = 0;
1792 }
1793 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1794 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1795
1796 for ( int32_t q = 0; q < 8; q++ )
1797 {
1798 initD[q] = other.initD[q];
1799 weap_initiald[q] = other.weap_initiald[q];
1800 }
1801 for ( int32_t q = 0; q < 2; q++ )
1802 {
1803 initA[q] = other.initA[q];
1804 weap_initiala[q] = other.weap_initiala[q];
1805 }
1806 }
1807
1808 esMoldorm::esMoldorm(esMoldorm const & other, bool new_script_uid, bool clear_parent_script_UID):
1809 //Struct Element Type Purpose
1810 //sprite(other),
1811 enemy(other),
1812 parentclk(other.parentclk)
1813 {
1814
1815 //arrays
1816
1817 if(other.scrmem)
1818 {
1819 alloc_scriptmem();
1820 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1821
1822 scrmem->scriptData = other.scrmem->scriptData;
1823 }
1824 else scrmem = NULL;
1825 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1826 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1827
1828 for(int32_t i=0; i<edefLAST255; i++)
1829 defense[i]=other.defense[i];
1830 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1831 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1832
1833 if(new_script_uid)
1834 {
1835 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1836 }
1837 if(clear_parent_script_UID)
1838 {
1839 parent_script_UID = 0;
1840 }
1841 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1842 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1843
1844 for ( int32_t q = 0; q < 8; q++ )
1845 {
1846 initD[q] = other.initD[q];
1847 weap_initiald[q] = other.weap_initiald[q];
1848 }
1849 for ( int32_t q = 0; q < 2; q++ )
1850 {
1851 initA[q] = other.initA[q];
1852 weap_initiala[q] = other.weap_initiala[q];
1853 }
1854 }
1855 /*
1856 eManhandla::eManhandla(eManhandla const & other, bool new_script_uid, bool clear_parent_script_UID):
1857 //Struct Element Type Purpose
1858 //sprite(other),
1859 enemy(other),
1860 armcnt(armcnt),
1861 adjusted(adjusted),
1862 arm[0](arm[0]),
1863 arm[1](arm[1]),
1864 arm[2](arm[2]),
1865 arm[3](arm[3]),
1866 arm[4](arm[4]),
1867 arm[5](arm[5]),
1868 arm[6](arm[6]),
1869 arm[7](arm[7])
1870 {
1871
1872 //arrays
1873 if(other.scrmem)
1874 {
1875 alloc_scriptmem();
1876 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1877
1878 scrmem->scriptData = other.scrmem->scriptData;
1879 }
1880 else scrmem = NULL;
1881 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1882 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1883
1884 for(int32_t i=0; i<edefLAST255; i++)
1885 defense[i]=other.defense[i];
1886 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1887 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1888
1889 if(new_script_uid)
1890 {
1891 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1892 }
1893 if(clear_parent_script_UID)
1894 {
1895 parent_script_UID = 0;
1896 }
1897 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1898 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1899
1900 for ( int32_t q = 0; q < 8; q++ )
1901 {
1902 initD[q] = other.initD[q];
1903 weap_initiald[q] = other.weap_initiald[q];
1904 }
1905 for ( int32_t q = 0; q < 2; q++ )
1906 {
1907 initA[q] = other.initA[q];
1908 weap_initiala[q] = other.weap_initiala[q];
1909 }
1910 }
1911
1912 esManhandla::esManhandla(esManhandla const & other, bool new_script_uid, bool clear_parent_script_UID):
1913 //Struct Element Type Purpose
1914 //sprite(other),
1915 enemy(other)
1916 {
1917
1918 //arrays
1919 if(other.scrmem)
1920 {
1921 alloc_scriptmem();
1922 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1923
1924 scrmem->scriptData = other.scrmem->scriptData;
1925 }
1926 else scrmem = NULL;
1927 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1928 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1929
1930 for(int32_t i=0; i<edefLAST255; i++)
1931 defense[i]=other.defense[i];
1932 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1933 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1934
1935 if(new_script_uid)
1936 {
1937 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1938 }
1939 if(clear_parent_script_UID)
1940 {
1941 parent_script_UID = 0;
1942 }
1943 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1944 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1945
1946 for ( int32_t q = 0; q < 8; q++ )
1947 {
1948 initD[q] = other.initD[q];
1949 weap_initiald[q] = other.weap_initiald[q];
1950 }
1951 for ( int32_t q = 0; q < 2; q++ )
1952 {
1953 initA[q] = other.initA[q];
1954 weap_initiala[q] = other.weap_initiala[q];
1955 }
1956 }
1957
1958 eGleeok::eGleeok(eGleeok const & other, bool new_script_uid, bool clear_parent_script_UID):
1959 //Struct Element Type Purpose
1960 //sprite(other),
1961 enemy(other),
1962 flameclk(flameclk),
1963 flamehead(flamehead),
1964 necktile(necktile)
1965
1966 {
1967
1968 //arrays
1969
1970 if(other.scrmem)
1971 {
1972 alloc_scriptmem();
1973 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
1974
1975 scrmem->scriptData = other.scrmem->scriptData;
1976 }
1977 else scrmem = NULL;
1978 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
1979 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
1980
1981 for(int32_t i=0; i<edefLAST255; i++)
1982 defense[i]=other.defense[i];
1983 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
1984 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
1985
1986 if(new_script_uid)
1987 {
1988 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
1989 }
1990 if(clear_parent_script_UID)
1991 {
1992 parent_script_UID = 0;
1993 }
1994 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
1995 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
1996
1997 for ( int32_t q = 0; q < 8; q++ )
1998 {
1999 initD[q] = other.initD[q];
2000 weap_initiald[q] = other.weap_initiald[q];
2001 }
2002 for ( int32_t q = 0; q < 2; q++ )
2003 {
2004 initA[q] = other.initA[q];
2005 weap_initiala[q] = other.weap_initiala[q];
2006 }
2007 }
2008
2009 esGleeok::esGleeok(esGleeok const & other, bool new_script_uid, bool clear_parent_script_UID):
2010 //Struct Element Type Purpose
2011 //sprite(other),
2012 enemy(other),
2013 headtile(headtile),
2014 flyingheadtile(flyingheadtile),
2015 necktile(necktile),
2016 xoffset(xoffset),
2017 yoffset(yoffset),
2018 nx(nx),
2019 ny(ny),
2020 nxoffset(nxoffset),
2021 nyoffset(nyoffset),
2022 parent(parent)
2023
2024 {
2025
2026 //arrays
2027
2028 if(other.scrmem)
2029 {
2030 alloc_scriptmem();
2031 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2032
2033 scrmem->scriptData = other.scrmem->scriptData;
2034 }
2035 else scrmem = NULL;
2036 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2037 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2038
2039 //for ( int32_t q = 0; q < 255; q++ )
2040 //{
2041 // nx[q] = other.nx[q];
2042 // ny[q] = other.ny[q];
2043 // nxoffset[q] = other.nxoffset[q];
2044 // nyoffset[q] = other.nyoffset[q];
2045 //}
2046
2047 for(int32_t i=0; i<edefLAST255; i++)
2048 defense[i]=other.defense[i];
2049 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2050 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2051
2052 if(new_script_uid)
2053 {
2054 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2055 }
2056 if(clear_parent_script_UID)
2057 {
2058 parent_script_UID = 0;
2059 }
2060 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2061 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2062
2063 for ( int32_t q = 0; q < 8; q++ )
2064 {
2065 initD[q] = other.initD[q];
2066 weap_initiald[q] = other.weap_initiald[q];
2067 }
2068 for ( int32_t q = 0; q < 2; q++ )
2069 {
2070 initA[q] = other.initA[q];
2071 weap_initiala[q] = other.weap_initiala[q];
2072 }
2073 }
2074
2075 ePatra::ePatra(ePatra const & other, bool new_script_uid, bool clear_parent_script_UID):
2076 //Struct Element Type Purpose
2077 //sprite(other),
2078 enemy(other),
2079 flycnt(flycnt),
2080 flycnt2(flycnt2),
2081 loopcnt(loopcnt),
2082 lookat(lookat),
2083 circle_x(circle_x),
2084 circle_y(circle_y),
2085 temp_x(temp_x),
2086 temp_y(temp_y),
2087 adjusted(adjusted)
2088
2089 {
2090
2091 //arrays
2092
2093 if(other.scrmem)
2094 {
2095 alloc_scriptmem();
2096 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2097
2098 scrmem->scriptData = other.scrmem->scriptData;
2099 }
2100 else scrmem = NULL;
2101 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2102 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2103
2104 for(int32_t i=0; i<edefLAST255; i++)
2105 defense[i]=other.defense[i];
2106 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2107 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2108
2109 if(new_script_uid)
2110 {
2111 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2112 }
2113 if(clear_parent_script_UID)
2114 {
2115 parent_script_UID = 0;
2116 }
2117 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2118 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2119
2120 for ( int32_t q = 0; q < 8; q++ )
2121 {
2122 initD[q] = other.initD[q];
2123 weap_initiald[q] = other.weap_initiald[q];
2124 }
2125 for ( int32_t q = 0; q < 2; q++ )
2126 {
2127 initA[q] = other.initA[q];
2128 weap_initiala[q] = other.weap_initiala[q];
2129 }
2130 }
2131
2132 ePatraBS::ePatraBS(ePatraBS const & other, bool new_script_uid, bool clear_parent_script_UID):
2133 //Struct Element Type Purpose
2134 //sprite(other),
2135 enemy(other),
2136 flycnt(flycnt),
2137 flycnt2(flycnt2),
2138 loopcnt(loopcnt),
2139 lookat(lookat),
2140 adjusted(adjusted)
2141
2142 {
2143
2144 //arrays
2145
2146 if(other.scrmem)
2147 {
2148 alloc_scriptmem();
2149 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2150
2151 scrmem->scriptData = other.scrmem->scriptData;
2152 }
2153 else scrmem = NULL;
2154 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2155 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2156
2157 for(int32_t i=0; i<edefLAST255; i++)
2158 defense[i]=other.defense[i];
2159 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2160 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2161
2162 if(new_script_uid)
2163 {
2164 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2165 }
2166 if(clear_parent_script_UID)
2167 {
2168 parent_script_UID = 0;
2169 }
2170 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2171 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2172
2173 for ( int32_t q = 0; q < 8; q++ )
2174 {
2175 initD[q] = other.initD[q];
2176 weap_initiald[q] = other.weap_initiald[q];
2177 }
2178 for ( int32_t q = 0; q < 2; q++ )
2179 {
2180 initA[q] = other.initA[q];
2181 weap_initiala[q] = other.weap_initiala[q];
2182 }
2183 }
2184
2185 esPatra::esPatra(esPatra const & other, bool new_script_uid, bool clear_parent_script_UID):
2186 //Struct Element Type Purpose
2187 //sprite(other),
2188 enemy(other)
2189
2190 {
2191
2192 //arrays
2193
2194 if(other.scrmem)
2195 {
2196 alloc_scriptmem();
2197 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2198
2199 scrmem->scriptData = other.scrmem->scriptData;
2200 }
2201 else scrmem = NULL;
2202 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2203 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2204
2205 for ( int32_t q = 0; q < 255; q++ )
2206 {
2207 nx[q] = other.nx[q];
2208 ny[q] = other.ny[q];
2209 nxoffset[q] = other.nxoffset[q];
2210 nyoffset[q] = other.nyoffset[q];
2211 }
2212
2213 for(int32_t i=0; i<edefLAST255; i++)
2214 defense[i]=other.defense[i];
2215 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2216 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2217
2218 if(new_script_uid)
2219 {
2220 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2221 }
2222 if(clear_parent_script_UID)
2223 {
2224 parent_script_UID = 0;
2225 }
2226 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2227 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2228
2229 for ( int32_t q = 0; q < 8; q++ )
2230 {
2231 initD[q] = other.initD[q];
2232 weap_initiald[q] = other.weap_initiald[q];
2233 }
2234 for ( int32_t q = 0; q < 2; q++ )
2235 {
2236 initA[q] = other.initA[q];
2237 weap_initiala[q] = other.weap_initiala[q];
2238 }
2239 }
2240
2241 esPatraBS::esPatraBS(esPatraBS const & other, bool new_script_uid, bool clear_parent_script_UID):
2242 //Struct Element Type Purpose
2243 //sprite(other),
2244 enemy(other)
2245
2246 {
2247
2248 //arrays
2249
2250 if(other.scrmem)
2251 {
2252 alloc_scriptmem();
2253 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2254
2255 scrmem->scriptData = other.scrmem->scriptData;
2256 }
2257 else scrmem = NULL;
2258 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2259 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2260
2261 for ( int32_t q = 0; q < 255; q++ )
2262 {
2263 nx[q] = other.nx[q];
2264 ny[q] = other.ny[q];
2265 nxoffset[q] = other.nxoffset[q];
2266 nyoffset[q] = other.nyoffset[q];
2267 }
2268
2269 for(int32_t i=0; i<edefLAST255; i++)
2270 defense[i]=other.defense[i];
2271 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2272 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2273
2274 if(new_script_uid)
2275 {
2276 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2277 }
2278 if(clear_parent_script_UID)
2279 {
2280 parent_script_UID = 0;
2281 }
2282 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2283 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2284
2285 for ( int32_t q = 0; q < 8; q++ )
2286 {
2287 initD[q] = other.initD[q];
2288 weap_initiald[q] = other.weap_initiald[q];
2289 }
2290 for ( int32_t q = 0; q < 2; q++ )
2291 {
2292 initA[q] = other.initA[q];
2293 weap_initiala[q] = other.weap_initiala[q];
2294 }
2295 }
2296
2297 */
2298
2299
5/10
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 436 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 436 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 436 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 436 times.
✗ Branch 9 not taken.
1308 enemy::enemy(zfix X,zfix Y,int32_t Id,int32_t Clk) : sprite()
2300 872 {
2301
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 x=X;
2302
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 y=Y;
2303 436 id=Id;
2304 436 clk=Clk;
2305
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 floor_y=y;
2306 436 ceiling=false;
2307 436 fading = misc = clk2 = clk3 = stunclk = hclk = sclk = superman = 0;
2308 436 grumble = movestatus = posframe = timer = ox = oy = 0;
2309
4/8
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 436 times.
✓ Branch 4 taken 436 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 436 times.
✗ Branch 7 not taken.
436 yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) - ((isSideViewGravity()) ? 0 : 2);
2310 436 did_armos=true;
2311 436 script_spawned=false;
2312
2313 436 d = guysbuf + (id & 0xFFF);
2314 436 hp = d->hp;
2315 436 starting_hp = hp;
2316 // cs = d->cset;
2317 //d variables
2318
2319 436 flags=d->flags;
2320 436 flags2=d->flags2;
2321 436 s_tile=d->s_tile; //secondary (additional) tile(s)
2322 436 family=d->family;
2323 436 dcset=d->cset;
2324 436 cs=dcset;
2325
3/4
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 226 times.
✓ Branch 3 taken 210 times.
436 anim=get_bit(quest_rules,qr_NEWENEMYTILES)?d->e_anim:d->anim;
2326 436 dp=d->dp;
2327 436 wdp=d->wdp;
2328 436 wpn=d->weapon;
2329 436 wpnsprite = d-> wpnsprite; //2.6 -Z
2330 436 rate=d->rate;
2331 436 hrate=d->hrate;
2332
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 dstep=d->step;
2333 436 homing=d->homing;
2334 436 dmisc1=d->misc1;
2335 436 dmisc2=d->misc2;
2336 436 dmisc3=d->misc3;
2337 436 dmisc4=d->misc4;
2338 436 dmisc5=d->misc5;
2339 436 dmisc6=d->misc6;
2340 436 dmisc7=d->misc7;
2341 436 dmisc8=d->misc8;
2342 436 dmisc9=d->misc9;
2343 436 dmisc10=d->misc10;
2344 436 dmisc11=d->misc11;
2345 436 dmisc12=d->misc12;
2346 436 dmisc13=d->misc13;
2347 436 dmisc14=d->misc14;
2348 436 dmisc15=d->misc15;
2349 436 dmisc16=d->misc16;
2350 436 dmisc17=d->misc17;
2351 436 dmisc18=d->misc18;
2352 436 dmisc19=d->misc19;
2353 436 dmisc20=d->misc20;
2354 436 dmisc21=d->misc21;
2355 436 dmisc22=d->misc22;
2356 436 dmisc23=d->misc23;
2357 436 dmisc24=d->misc24;
2358 436 dmisc25=d->misc25;
2359 436 dmisc26=d->misc26;
2360 436 dmisc27=d->misc27;
2361 436 dmisc28=d->misc28;
2362 436 dmisc29=d->misc29;
2363 436 dmisc30=d->misc30;
2364 436 dmisc31=d->misc31;
2365 436 dmisc32=d->misc32;
2366
3/4
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 388 times.
✓ Branch 3 taken 48 times.
436 if (get_bit(quest_rules, qr_BROKEN_ATTRIBUTE_31_32))
2367 {
2368 388 dmisc31 = dmisc32;
2369 388 dmisc32 = 0;
2370 388 }
2371 436 spr_shadow=d->spr_shadow;
2372 436 spr_death=d->spr_death;
2373 436 spr_spawn=d->spr_spawn;
2374
2375
2/2
✓ Branch 0 taken 17876 times.
✓ Branch 1 taken 436 times.
18312 for(int32_t i=0; i<edefLAST255; i++)
2376 17876 defense[i]=d->defense[i];
2377
2378 436 bgsfx=d->bgsfx;
2379 436 hitsfx=d->hitsfx;
2380 436 deadsfx=d->deadsfx;
2381 436 bosspal=d->bosspal;
2382 436 parent_script_UID = 0;
2383
2384 436 frozentile = d->frozentile;
2385
2386 436 frozencset = d->frozencset;
2387 436 frozenclock = 0;
2388
2/2
✓ Branch 0 taken 4360 times.
✓ Branch 1 taken 436 times.
4796 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = d->frozenmisc[q];
2389
2390
2/2
✓ Branch 0 taken 436 times.
✓ Branch 1 taken 6976 times.
7412 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = 0;
2391 //firesfx = 0; //t.b.a -Z
2392 436 isCore = true; //t.b.a
2393 436 parentCore = 0; //t.b.a
2394
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2395
2396 436 firesfx = d->firesfx;
2397
2/2
✓ Branch 0 taken 13952 times.
✓ Branch 1 taken 436 times.
14388 for ( int32_t q = 0; q < 32; q++ ) movement[q] = d->movement[q];
2398
2/2
✓ Branch 0 taken 13952 times.
✓ Branch 1 taken 436 times.
14388 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = d->new_weapon[q];
2399
2400
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 script = (d->script >= 0) ? d->script : 0; //Dont assign invalid data.
2401 436 waitdraw = 0;
2402
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 weaponscript = (d->weaponscript >= 0) ? d->weaponscript : 0; //Dont assign invalid data.
2403
2404
2/2
✓ Branch 0 taken 3488 times.
✓ Branch 1 taken 436 times.
3924 for ( int32_t q = 0; q < 8; q++ )
2405 {
2406 3488 initD[q] = d->initD[q];
2407 //Z_scripterrlog("(enemy::enemy(zfix)): Loading weapon InitD[%d] to an enemy with a value of (%d)\n",q,d->weap_initiald[q]);
2408 3488 weap_initiald[q] = d->weap_initiald[q];
2409 //al_trace("Guys.cpp: Assigning guy.initD[%d]: %d\n",q, d->initD.initD[q]);
2410 //al_trace("Guys.cpp: Assigning guy.initD[%d] from d->initD[%d]: %d\n",q,q, d->initD[q]);
2411 //al_trace("Guys.cpp: guy.initD[%d] is: %d\n",q, initD[q]);
2412 3488 }
2413
2/2
✓ Branch 0 taken 872 times.
✓ Branch 1 taken 436 times.
1308 for ( int32_t q = 0; q < 2; q++ )
2414 {
2415 872 initA[q] = d->initA[q];
2416 872 weap_initiala[q] = d->weap_initiala[q];
2417 872 }
2418
2419 436 stickclk = 0;
2420 436 submerged = false;
2421 436 ffcactivated = 0;
2422 436 hitdir = -1;
2423 436 dialogue_str = 0; //set by spawn flags.
2424 436 editorflags = d->editorflags; //set by Enemy Editor
2425 //Set the drawing flag for this sprite.
2426
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 if ( (editorflags&ENEMY_FLAG12) ) { drawflags |= sprdrawflagALWAYSOLDDRAWS; }
2427
2428
2429
2/2
✓ Branch 0 taken 161 times.
✓ Branch 1 taken 275 times.
436 if(bosspal>-1)
2430 {
2431
1/2
✓ Branch 0 taken 161 times.
✗ Branch 1 not taken.
161 loadpalset(csBOSS,pSprite(bosspal));
2432 161 }
2433
2434
2/2
✓ Branch 0 taken 244 times.
✓ Branch 1 taken 192 times.
436 if(bgsfx>-1)
2435 {
2436
1/2
✓ Branch 0 taken 244 times.
✗ Branch 1 not taken.
244 cont_sfx(bgsfx);
2437 244 }
2438
2439
3/4
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 226 times.
✓ Branch 3 taken 210 times.
436 if(get_bit(quest_rules,qr_NEWENEMYTILES))
2440 {
2441 226 o_tile=d->e_tile;
2442 226 frate = d->e_frate;
2443 226 }
2444 else
2445 {
2446 210 o_tile=d->tile;
2447 210 frate = d->frate;
2448 }
2449
2450 436 tile=0; //init to 0 here, but set it later.
2451
2452 436 scripttile = -1;
2453 436 scriptflip = -1;
2454 436 do_animation = 1;
2455 436 immortal = false;
2456 436 noSlide = false;
2457 436 deathexstate = -1;
2458
2459 436 hashero=false;
2460
2461 // If they forgot the invisibility flag, here's another failsafe:
2462
3/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 427 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
436 if(o_tile==0 && family!=eeSPINTILE)
2463 9 flags |= guy_invisible;
2464
2465 // step = d->step/100.0;
2466 // To preserve the odd step values for Keese & Gleeok heads. -L
2467
5/8
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 436 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88 times.
✓ Branch 5 taken 348 times.
✓ Branch 6 taken 88 times.
✗ Branch 7 not taken.
436 if(dstep==62.0) dstep+=0.5;
2468
3/8
✓ Branch 0 taken 348 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 348 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 348 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
348 else if(dstep==89) dstep-=1/9;
2469
2470
5/10
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 436 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 436 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 436 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 436 times.
✗ Branch 9 not taken.
436 step = zslongToFix(dstep*100);
2471
2472
2473 436 item_set = d->item_set;
2474 436 grumble = d->grumble;
2475
2476
2/2
✓ Branch 0 taken 327 times.
✓ Branch 1 taken 109 times.
436 if(frate == 0)
2477 109 frate = 256;
2478
2479 436 leader = itemguy = dying = scored = false;
2480 436 canfreeze = count_enemy = true;
2481 436 mainguy = !(flags & guy_doesntcount);
2482
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 dir = zc_oldrand()&3;
2483
2484 //2.6 Enemy Editor Hit and TIle Sizes
2485
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
436 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
2486 //al_trace("->txsz:%i\n", d->txsz); Verified that this is setting the value. -Z
2487 // al_trace("Enemy txsz:%i\n", txsz);
2488
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
436 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
2489
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
436 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
2490
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
436 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
2491
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
436 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
2492
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
2493
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
2494 // if ( (d->SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = d->hzofs;
2495
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
436 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
2496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 436 times.
436 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
2497 {
2498 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
2499 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
2500 }
2501
2502
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
436 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
2503
2504 436 SIZEflags = d->SIZEflags;
2505
2506
2/10
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 436 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
436 if((wpn==ewBomb || wpn==ewSBomb) && family!=eeOTHER && family!=eeFIRE && (family!=eeWALK || dmisc2 != e2tBOMBCHU))
2507 wpn = 0;
2508
2509 //tile should never be 0 after init --Z (failsafe)
2510
4/6
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 436 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 388 times.
✓ Branch 5 taken 48 times.
436 if (tile <= 0 && FFCore.getQuestHeaderInfo(vZelda) >= 0x255) {tile = o_tile;}
2511
2512 //Moveflags; for gravity and pit interaction
2513 436 moveflags = d->moveflags;
2514
3/4
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 392 times.
✓ Branch 3 taken 44 times.
436 if(!can_pitfall(false))
2515 {
2516 //Some enemies must not interact with pits. Force their flags, for sanity's sake.
2517 44 moveflags &= ~FLAG_CAN_PITFALL;
2518 44 moveflags &= ~FLAG_CAN_WATERDROWN;
2519 44 }
2520
2521
1/2
✓ Branch 0 taken 436 times.
✗ Branch 1 not taken.
436 shieldCanBlock = get_bit(quest_rules,qr_GOHMA_UNDAMAGED_BUG)?true:false;
2522 436 }
2523
2524 //base clone constructor
2525
2526 enemy::enemy(enemy const & other, bool new_script_uid, bool clear_parent_script_UID):
2527 //Struct Element Type Purpose
2528 sprite(other),
2529 //x(other.x), //int32_t
2530 //y(other.y), //int32_t
2531 //id(other.id), //int32_t
2532 //clk(other.clk), //int32_t
2533 floor_y(other.floor_y), //int32_t
2534 fading(other.fading), //int32_t
2535 //misc(other.misc), //int32_t
2536 clk2(other.clk2), //int32_t
2537 clk3(other.clk3), //int32_t
2538 stunclk(other.stunclk), //int32_t
2539 hclk(other.hclk), //int32_t
2540 sclk(other.sclk), //int32_t
2541 superman(other.superman), //int32_t
2542 //grumble(other.grumble), //int32_t
2543 movestatus(other.movestatus), //int32_t
2544 posframe(other.posframe), //int32_t
2545 timer(other.timer), //int32_t
2546 ox(other.ox), //int32_t
2547 oy(other.oy), //int32_t
2548 //yofs(other.yofs), //int32_t
2549 did_armos(other.did_armos), //int32_t
2550 script_spawned(other.script_spawned), //int32_t
2551 d(other.d), //int32_t
2552 hp(other.hp), //int32_t
2553 starting_hp(other.starting_hp), //int32_t
2554 //flags(other.flags), //int32_t
2555
2556 flags2(other.flags2), //int32_t
2557 s_tile(other.s_tile), //int32_t
2558 family(other.family), //int32_t
2559 dcset(other.dcset), //int32_t
2560 //cs(other.cs), //int32_t
2561 anim(other.anim), //int32_t
2562 dp(other.dp), //int32_t
2563 wdp(other.wdp), //int32_t
2564 wpnsprite(other.wpnsprite), //int32_t
2565 rate(other.rate), //int32_t
2566 hrate(other.hrate), //int32_t
2567 dstep(other.dstep), //int32_t
2568
2569 homing(other.homing), //int32_t
2570 dmisc1(other.dmisc1), //int32_t
2571 dmisc2(other.dmisc2), //int32_t
2572 dmisc3(other.dmisc3), //int32_t
2573 dmisc4(other.dmisc4), //int32_t
2574 dmisc5(other.dmisc5), //int32_t
2575 dmisc6(other.dmisc6), //int32_t
2576 dmisc7(other.dmisc7), //int32_t
2577 dmisc8(other.dmisc8), //int32_t
2578 dmisc9(other.dmisc9), //int32_t
2579 dmisc10(other.dmisc10), //int32_t
2580 dmisc11(other.dmisc11), //int32_t
2581 dmisc12(other.dmisc12), //int32_t
2582 dmisc13(other.dmisc13), //int32_t
2583 dmisc14(other.dmisc14), //int32_t
2584 dmisc15(other.dmisc15), //int32_t
2585 dmisc16(other.dmisc16), //int32_t
2586 dmisc17(other.dmisc17), //int32_t
2587 dmisc18(other.dmisc18), //int32_t
2588 dmisc19(other.dmisc19), //int32_t
2589 dmisc20(other.dmisc20), //int32_t
2590 dmisc21(other.dmisc21), //int32_t
2591 dmisc22(other.dmisc22), //int32_t
2592 dmisc23(other.dmisc23), //int32_t
2593 dmisc24(other.dmisc24), //int32_t
2594 dmisc25(other.dmisc25), //int32_t
2595 dmisc26(other.dmisc26), //int32_t
2596 dmisc27(other.dmisc27), //int32_t
2597 dmisc28(other.dmisc28), //int32_t
2598 dmisc29(other.dmisc29), //int32_t
2599 dmisc30(other.dmisc30), //int32_t
2600 dmisc31(other.dmisc31), //int32_t
2601 dmisc32(other.dmisc32), //int32_t
2602 bgsfx(other.bgsfx), //int32_t
2603 hitsfx(other.hitsfx), //int32_t
2604 deadsfx(other.deadsfx), //int32_t
2605 bosspal(other.bosspal), //int32_t
2606 parent_script_UID(other.parent_script_UID), //int32_t
2607 frozentile(other.frozentile), //int32_t
2608 frozencset(other.frozencset), //int32_t
2609 frozenclock(other.frozenclock), //int32_t
2610 isCore(other.isCore), //int32_t
2611 parentCore(other.parentCore), //int32_t
2612 script_UID(other.script_UID), //int32_t
2613 firesfx(other.firesfx), //int32_t
2614 //script(other.script), //int32_t
2615 //waitdraw(other.waitdraw), //int32_t
2616 weaponscript(other.weaponscript), //int32_t
2617 stickclk(other.stickclk), //int32_t
2618 hitdir(other.hitdir), //int32_t
2619 submerged(other.submerged), //int32_t
2620 ffcactivated(other.ffcactivated), //word
2621
2622 dialogue_str(other.dialogue_str), //int32_t
2623 editorflags(other.editorflags), //int32_t
2624 //drawflags(other.drawflags), //int32_t
2625 o_tile(other.o_tile), //int32_t
2626 frate(other.frate), //int32_t
2627 //tile(other.tile), //int32_t
2628 //scripttile(other.scripttile), //int32_t
2629 //scriptflip(other.scriptflip), //int32_t
2630 //do_animation(other.do_animation), //int32_t
2631 immortal(other.immortal), //bool
2632 noSlide(other.noSlide), //bool
2633 deathexstate(other.deathexstate), //int32_t
2634 flags(other.flags), //int32_t
2635 step(other.step), //int32_t
2636
2637 item_set(other.item_set), //int32_t
2638 grumble(other.grumble), //int32_t
2639 leader(other.leader), //int32_t
2640 itemguy(other.itemguy), //int32_t
2641 dying(other.dying), //int32_t
2642 scored(other.scored), //int32_t
2643 //canfreeze(other.canfreeze), //int32_t
2644 count_enemy(other.count_enemy), //int32_t
2645 mainguy(other.mainguy), //int32_t
2646 //dir(other.dir), //int32_t
2647
2648 //txsz(other.txsz), //int32_t
2649 //tysz(other.tysz), //int32_t
2650 //hxsz(other.hxsz), //int32_t
2651 //hysz(other.hysz), //int32_t
2652 //hzsz(other.hzsz), //int32_t
2653 //hxofs(other.hxofs), //int32_t
2654 //hxofs(other.hxofs), //int32_t
2655 //xofs(other.xofs), //int32_t
2656 //yofs(other.yofs), //int32_t
2657 //hzofs(other.hzofs), //int32_t
2658 //zofs(other.zofs), //int32_t
2659
2660 wpn(other.wpn), //int32_t
2661 SIZEflags(other.SIZEflags), //int32_t
2662 hashero(other.hashero)
2663
2664 {
2665
2666 //arrays
2667
2668 if(other.scrmem)
2669 {
2670 alloc_scriptmem();
2671 memcpy(scrmem->stack, other.scrmem->stack, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
2672
2673 scrmem->scriptData = other.scrmem->scriptData;
2674 }
2675 else scrmem = NULL;
2676 //memset((refInfo)scriptData, 0xFFFF, sizeof(refInfo));
2677 //memset((refInfo)scriptData, other.scriptData, sizeof(refInfo));
2678
2679 for(int32_t i=0; i<edefLAST255; i++)
2680 defense[i]=other.defense[i];
2681 for ( int32_t q = 0; q < 10; q++ ) frozenmisc[q] = other.frozenmisc[q];
2682 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) hitby[q] = other.hitby[q];
2683
2684 if(new_script_uid)
2685 {
2686 script_UID = FFCore.GetScriptObjectUID(UID_TYPE_NPC); //This is used by child npcs.
2687 }
2688 if(clear_parent_script_UID)
2689 {
2690 parent_script_UID = 0;
2691 }
2692 for ( int32_t q = 0; q < 32; q++ ) movement[q] = other.movement[q];
2693 for ( int32_t q = 0; q < 32; q++ ) new_weapon[q] = other.new_weapon[q];
2694
2695 for ( int32_t q = 0; q < 8; q++ )
2696 {
2697 initD[q] = other.initD[q];
2698 weap_initiald[q] = other.weap_initiald[q];
2699 }
2700 for ( int32_t q = 0; q < 2; q++ )
2701 {
2702 initA[q] = other.initA[q];
2703 weap_initiala[q] = other.weap_initiala[q];
2704 }
2705 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
2706 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
2707 // al_trace("Enemy txsz:%i\n", txsz);
2708 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
2709 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
2710 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
2711 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
2712 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
2713 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
2714 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
2715 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
2716 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
2717 {
2718 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
2719 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
2720 }
2721
2722 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
2723
2724
2725
2726
2727 }
2728
2729
2730 int32_t enemy::getScriptUID() { return script_UID; }
2731 void enemy::setScriptUID(int32_t new_id) { script_UID = new_id; }
2732 433 enemy::~enemy()
2733 433 {
2734
2/4
✓ Branch 0 taken 433 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 433 times.
✗ Branch 3 not taken.
433 FFCore.deallocateAllArrays(SCRIPT_NPC, getUID());
2735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 433 times.
433 if(hashero)
2736 {
2737 Hero.setEaten(0);
2738 hashero=false;
2739 }
2740 433 }
2741
2742
2743 bool enemy::is_move_paused()
2744 {
2745 return (clk<0 || dying || stunclk || watch || ceiling || frozenclock || fallclk || drownclk);
2746 }
2747
2748 11304 bool enemy::scr_walkflag(int32_t dx,int32_t dy,int32_t special, int32_t dir, int32_t input_x, int32_t input_y, bool kb)
2749 {
2750 11304 int32_t yg = (special==spw_floater)?8:0;
2751 11304 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
2752 //Z_eventlog("Checking x,y %d,%d\n",dx,dy);
2753
1/2
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
11304 if(input_x == -1000)
2754 input_x = dx;
2755
1/2
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
11304 if(input_y == -1000)
2756 input_y = dy;
2757
2758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11304 times.
22608 if(!(moveflags & FLAG_IGNORE_SCREENEDGE)
2759
3/6
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11304 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 11304 times.
11304 && (input_x<16-nb || input_y<zc_max(16-yg-nb,0)
2760
2/4
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11304 times.
✗ Branch 3 not taken.
11304 || input_x>=240+nb-hxsz || input_y>=160+nb-hysz))
2761 return true;
2762
2763
3/6
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11304 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11304 times.
✗ Branch 5 not taken.
11304 if(!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL) || !kb)) //Don't walk into pits, unless being knocked back
2764 {
2765 if(ispitfall(dx,dy))
2766 return true;
2767 }
2768
2769 11304 bool flying = false;
2770 11304 bool cansolid = false;
2771
1/2
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
11304 if(moveflags & FLAG_IGNORE_SOLIDITY)
2772 cansolid = true;
2773
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11304 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11304 switch(special)
2774 {
2775 case spw_clipbottomright:
2776 if(dy>=128 || dx>=208) return true;
2777 break;
2778 case spw_clipright:
2779 break; //if(input_x>=208) return true; break;
2780
2781 case spw_wizzrobe: // fall through
2782 case spw_floater: // Special case for fliers and wizzrobes - hack!
2783 {
2784 if(isdungeon() && !(moveflags & FLAG_IGNORE_SCREENEDGE))
2785 {
2786 if(dy < 32-yg || dy >= 144) return true;
2787 if(dx < 32 || dx >= 224) return true;
2788 }
2789 if(!(moveflags & FLAG_IGNORE_BLOCKFLAGS) && flyerblocked(dx, dy, special, kb))
2790 return true;
2791 cansolid = true;
2792 flying = true;
2793 }
2794 }
2795
2796 11304 dx &= ~7;
2797 11304 dy &= ~7;
2798
2799
3/6
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11304 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11304 times.
✗ Branch 5 not taken.
11304 if(!flying && !(moveflags & FLAG_IGNORE_BLOCKFLAGS) && groundblocked(dx,dy,kb)) return true;
2800
2801
4/8
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11304 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11304 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 11304 times.
11304 if (dx < 0 || dx > 255 || dy < 0 || dy > 175)
2802 return false;
2803 //_walkflag code
2804 mapscr *s1, *s2;
2805 11304 s1=(((*tmpscr).layermap[0]-1)>=0)?tmpscr2:NULL;
2806 11304 s2=(((*tmpscr).layermap[1]-1)>=0)?tmpscr2+1:NULL;
2807
2808 11304 int32_t cpos=(dx>>4)+(dy&0xF0);
2809
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11304 times.
✓ Branch 2 taken 8964 times.
✓ Branch 3 taken 2340 times.
11304 int32_t ci = tmpscr->data[cpos], ci1 = (s1?s1:tmpscr)->data[cpos], ci2 = (s2?s2:tmpscr)->data[cpos];
2810 11304 newcombo const& c = combobuf[ci];
2811 11304 newcombo const& c1 = combobuf[ci1];
2812 11304 newcombo const& c2 = combobuf[ci2];
2813
2814 11304 int32_t b=1;
2815
2/2
✓ Branch 0 taken 5447 times.
✓ Branch 1 taken 5857 times.
11304 if(dx&8) b<<=2;
2816
2/2
✓ Branch 0 taken 5885 times.
✓ Branch 1 taken 5419 times.
11304 if(dy&8) b<<=1;
2817
2818 #define iwtr(cmb, x, y, shallow) \
2819 (shallow \
2820 ? iswaterex(cmb, currmap, currscr, -1, dx, dy, false, false, false, true, false) \
2821 && !iswaterex(cmb, currmap, currscr, -1, dx, dy, false, false, false, false, false) \
2822 : iswaterex(cmb, currmap, currscr, -1, dx, dy, false, false, false, false, false))
2823 11304 bool wtr = iwtr(ci, dx, dy, false);
2824
1/2
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
11304 bool shwtr = iwtr(ci, dx, dy, true);
2825 11304 bool pit = ispitfall(dx,dy);
2826
2827
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11304 times.
✓ Branch 2 taken 11304 times.
✗ Branch 3 not taken.
11304 bool canwtr = (moveflags & FLAG_CAN_WATERWALK) || ((moveflags & FLAG_CAN_WATERDROWN) && kb);
2828
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11304 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11304 times.
11304 bool canpit = (moveflags & FLAG_CAN_PITWALK) || ((moveflags & FLAG_CAN_PITFALL) && kb);
2829 11304 bool needwtr = (moveflags & FLAG_ONLY_WATERWALK);
2830 11304 bool needshwtr = (moveflags & FLAG_ONLY_SHALLOW_WATERWALK);
2831 11304 bool needpit = (moveflags & FLAG_ONLY_PITWALK);
2832
2833 11304 int32_t cwalkflag = c.walk & 0xF;
2834
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11304 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
11304 if (c.type == cBRIDGE && get_bit(quest_rules, qr_OLD_BRIDGE_COMBOS)) cwalkflag = 0;
2835
1/2
✓ Branch 0 taken 11304 times.
✗ Branch 1 not taken.
11304 if (s1)
2836 {
2837 if (c1.type == cBRIDGE)
2838 {
2839 if (!get_bit(quest_rules, qr_OLD_BRIDGE_COMBOS))
2840 {
2841 int efflag = (c1.walk & 0xF0)>>4;
2842 int newsolid = (c1.walk & 0xF);
2843 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
2844 }
2845 else cwalkflag &= c1.walk;
2846 }
2847 else cwalkflag |= c1.walk & 0xF;
2848 }
2849
2/2
✓ Branch 0 taken 2340 times.
✓ Branch 1 taken 8964 times.
11304 if (s2)
2850 {
2851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8964 times.
8964 if (c2.type == cBRIDGE)
2852 {
2853 if (!get_bit(quest_rules, qr_OLD_BRIDGE_COMBOS))
2854 {
2855 int efflag = (c2.walk & 0xF0)>>4;
2856 int newsolid = (c2.walk & 0xF);
2857 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
2858 }
2859 else cwalkflag &= c2.walk;
2860 }
2861 8964 else cwalkflag |= c2.walk & 0xF;
2862 8964 }
2863 11304 bool solid = cwalkflag & b;
2864
3/4
✓ Branch 0 taken 1437 times.
✓ Branch 1 taken 9867 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1437 times.
11304 if (solid && !cansolid) return true;
2865
3/6
✓ Branch 0 taken 9867 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9867 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9867 times.
9867 if(needwtr || needshwtr || needpit)
2866 {
2867 bool ret = true;
2868 if (needwtr && wtr) ret = false;
2869 else if (needshwtr && shwtr) ret = false;
2870 else if (needpit && pit) ret = false;
2871 return ret;
2872 }
2873
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9867 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9867 else if(wtr && !canwtr)
2874 return true;
2875
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9867 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9867 else if(pit && !canpit)
2876 return true;
2877
2878 9867 return false;
2879 11304 }
2880
2881 4726 bool enemy::scr_canmove(zfix dx, zfix dy, int32_t special, bool kb, bool ign_sv)
2882 {
2883
3/4
✓ Branch 0 taken 3330 times.
✓ Branch 1 taken 1396 times.
✓ Branch 2 taken 3330 times.
✗ Branch 3 not taken.
4726 if(!(dx || dy)) return true;
2884 4726 zfix bx = x+hxofs, by = y+hyofs; //left/top
2885 4726 zfix rx = bx+hxsz-1, ry = by+hysz-1; //right/bottom
2886
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4726 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4726 if(!ign_sv && dy < 0) //check gravity
2887 {
2888 if((moveflags & FLAG_OBEYS_GRAV) && isSideViewGravity())
2889 return false;
2890 }
2891
2892
3/4
✓ Branch 0 taken 1396 times.
✓ Branch 1 taken 3330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1396 times.
4726 if(dx && !dy)
2893 {
2894
2/2
✓ Branch 0 taken 777 times.
✓ Branch 1 taken 619 times.
1396 if(dx < 0)
2895 {
2896
2/4
✓ Branch 0 taken 777 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 777 times.
777 special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
2897 777 int32_t tx = (bx+dx).getFloor();
2898
2/2
✓ Branch 0 taken 1554 times.
✓ Branch 1 taken 777 times.
2331 for(zfix ty = 0; by+ty < ry; ty += 8)
2899 {
2900
1/2
✓ Branch 0 taken 1554 times.
✗ Branch 1 not taken.
1554 if(scr_walkflag(tx, by+ty, special, left, bx, by, kb))
2901 return false;
2902 1554 }
2903
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 777 times.
777 if(scr_walkflag(tx, ry, special, left, bx, by, kb))
2904 return false;
2905 777 }
2906 else
2907 {
2908 619 int32_t tx = (rx+dx).getCeil();
2909
2/2
✓ Branch 0 taken 1238 times.
✓ Branch 1 taken 619 times.
1857 for(zfix ty = 0; by+ty < ry; ty += 8)
2910 {
2911
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 if(scr_walkflag(tx, by+ty, special, right, bx, by, kb))
2912 return false;
2913 1238 }
2914
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 619 times.
619 if(scr_walkflag(tx, ry, special, right, bx, by, kb))
2915 return false;
2916 }
2917 1396 }
2918
2/4
✓ Branch 0 taken 3330 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3330 times.
3330 else if(dy && !dx)
2919 {
2920
2/2
✓ Branch 0 taken 1795 times.
✓ Branch 1 taken 1535 times.
3330 if(dy < 0)
2921 {
2922
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1795 times.
1795 special = (special==spw_clipbottomright)?spw_none:special;
2923 1795 int32_t ty = (by+dy).getFloor();
2924
2/2
✓ Branch 0 taken 3590 times.
✓ Branch 1 taken 1795 times.
5385 for(zfix tx = 0; bx+tx < rx; tx += 8)
2925 {
2926
1/2
✓ Branch 0 taken 3590 times.
✗ Branch 1 not taken.
3590 if(scr_walkflag(bx+tx, ty, special, up, bx, by, kb))
2927 return false;
2928 3590 }
2929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1795 times.
1795 if(scr_walkflag(rx, ty, special, up, bx, by, kb))
2930 return false;
2931 1795 }
2932 else
2933 {
2934 1535 int32_t ty = (ry+dy).getCeil();
2935
2/2
✓ Branch 0 taken 1633 times.
✓ Branch 1 taken 98 times.
1731 for(zfix tx = 0; bx+tx < rx; tx += 8)
2936 {
2937
2/2
✓ Branch 0 taken 196 times.
✓ Branch 1 taken 1437 times.
1633 if(scr_walkflag(bx+tx, ty, special, down, bx, by, kb))
2938 1437 return false;
2939 196 }
2940
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98 times.
98 if(scr_walkflag(rx, ty, special, down, bx, by, kb))
2941 return false;
2942 }
2943 1893 }
2944 else
2945 {
2946 return scr_canmove(dx, 0, special, kb, ign_sv) && scr_canmove(dy, 0, special, kb, ign_sv);
2947 }
2948 3289 return true;
2949 4726 }
2950
2951 bool enemy::scr_canplace(zfix dx, zfix dy, int32_t special, bool kb)
2952 {
2953 zfix bx = dx+hxofs, by = dy+hyofs; //left/top
2954 zfix rx = bx+hxsz-1, ry = by+hysz-1; //right/bottom
2955
2956 for(zfix ty = 0; by+ty < ry; ty += 8)
2957 {
2958 for(zfix tx = 0; bx+tx < rx; tx += 8)
2959 {
2960 if(scr_walkflag(bx+tx, by+ty, special, -1, -1000, -1000, kb))
2961 return false;
2962 }
2963 if(scr_walkflag(rx, by+ty, special, -1, -1000, -1000, kb))
2964 return false;
2965 }
2966 for(zfix tx = 0; bx+tx < rx; tx += 8)
2967 {
2968 if(scr_walkflag(bx+tx, ry, special, -1, -1000, -1000, kb))
2969 return false;
2970 }
2971 if(scr_walkflag(rx, ry, special, -1, -1000, -1000, kb))
2972 return false;
2973 return true;
2974 }
2975
2976 3427 bool enemy::movexy(zfix dx, zfix dy, int32_t special, bool kb, bool ign_sv)
2977 {
2978 3427 bool ret = true;
2979
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 3427 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3427 if(!ign_sv && dy < 0 && (moveflags & FLAG_OBEYS_GRAV) && isSideViewGravity())
2980 dy = 0;
2981
4/4
✓ Branch 0 taken 3547 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 3427 times.
✓ Branch 3 taken 179 times.
3606 while(abs(dx) > 8 || abs(dy) > 8)
2982 {
2983
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 139 times.
179 if(abs(dx) > abs(dy))
2984 {
2985 40 int32_t tdx = dx.sign() * 8;
2986
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 if(movexy(tdx, 0, special, kb, ign_sv))
2987 40 dx -= tdx;
2988 else
2989 {
2990 dx = tdx;
2991 ret = false;
2992 }
2993 40 }
2994 else
2995 {
2996 139 int32_t tdy = dy.sign() * 8;
2997
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 136 times.
139 if(movexy(0, tdy, special, kb, ign_sv))
2998 3 dy -= tdy;
2999 else
3000 {
3001 136 dy = tdy;
3002 136 ret = false;
3003 }
3004 }
3005 }
3006
2/2
✓ Branch 0 taken 2031 times.
✓ Branch 1 taken 1396 times.
3427 if(dx)
3007 {
3008
1/2
✓ Branch 0 taken 1396 times.
✗ Branch 1 not taken.
1396 if(scr_canmove(dx, 0, special, kb, ign_sv))
3009 1396 x += dx;
3010 else
3011 {
3012 ret = false;
3013 int32_t xsign = dx.sign();
3014 while(scr_canmove(xsign, 0, special, kb, ign_sv))
3015 {
3016 x += xsign;
3017 dx -= xsign;
3018 }
3019 if(scr_canmove(dx.decsign(), 0, special, kb, ign_sv)) //can move 0.0001 to 0.9999 px in this direction
3020 {
3021 if(dx > 0)
3022 x.doCeil();
3023 else x.doFloor();
3024 }
3025 }
3026 1396 }
3027
2/2
✓ Branch 0 taken 1055 times.
✓ Branch 1 taken 2372 times.
3427 if(dy)
3028 {
3029
2/2
✓ Branch 0 taken 1893 times.
✓ Branch 1 taken 479 times.
2372 if(scr_canmove(0, dy, special, kb, ign_sv))
3030 1893 y += dy;
3031 else
3032 {
3033 479 ret = false;
3034 479 int32_t ysign = dy.sign();
3035
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 479 times.
479 while(scr_canmove(0, ysign, special, kb, ign_sv))
3036 {
3037 y += ysign;
3038 dy -= ysign;
3039 }
3040
1/2
✓ Branch 0 taken 479 times.
✗ Branch 1 not taken.
479 if(scr_canmove(0, dy.decsign(), special, kb, ign_sv)) //can move 0.0001 to 0.9999 px in this direction
3041 {
3042 if(dy > 0)
3043 y.doCeil();
3044 else y.doFloor();
3045 }
3046 }
3047 2372 }
3048 3427 return ret;
3049 }
3050
3051 bool enemy::moveDir(int32_t dir, zfix px, int32_t special, bool kb)
3052 {
3053 zfix diagrate = zslongToFix(7071);
3054 switch(NORMAL_DIR(dir))
3055 {
3056 case up:
3057 return movexy(0, -px, special, kb);
3058 case down:
3059 return movexy(0, px, special, kb);
3060 case left:
3061 return movexy(-px, 0, special, kb);
3062 case right:
3063 return movexy(px, 0, special, kb);
3064 case r_up:
3065 return movexy(px*diagrate, -px*diagrate, special, kb);
3066 case r_down:
3067 return movexy(px*diagrate, px*diagrate, special, kb);
3068 case l_up:
3069 return movexy(-px*diagrate, -px*diagrate, special, kb);
3070 case l_down:
3071 return movexy(-px*diagrate, px*diagrate, special, kb);
3072 }
3073 return false;
3074 }
3075
3076 bool enemy::moveAtAngle(zfix degrees, zfix px, int32_t special, bool kb)
3077 {
3078 double v = degrees.getFloat() * PI / 180.0;
3079 zfix dx = zc::math::Cos(v)*px, dy = zc::math::Sin(v)*px;
3080 return movexy(dx, dy, special, kb);
3081 }
3082
3083 bool enemy::can_movexy(zfix dx, zfix dy, int32_t special, bool kb)
3084 {
3085 zfix tx = x, ty = y;
3086 bool ret = movexy(dx, dy, special, kb);
3087 x = tx;
3088 y = ty;
3089 return ret;
3090 }
3091 bool enemy::can_moveDir(int32_t dir, zfix px, int32_t special, bool kb)
3092 {
3093 zfix tx = x, ty = y;
3094 bool ret = moveDir(dir, px, special, kb);
3095 x = tx;
3096 y = ty;
3097 return ret;
3098 }
3099 bool enemy::can_moveAtAngle(zfix degrees, zfix px, int32_t special, bool kb)
3100 {
3101 zfix tx = x, ty = y;
3102 bool ret = moveAtAngle(degrees, px, special, kb);
3103 x = tx;
3104 y = ty;
3105 return ret;
3106 }
3107
3108 // Handle pitfalls
3109 192390 bool enemy::do_falling(int32_t index)
3110 {
3111
1/2
✓ Branch 0 taken 192390 times.
✗ Branch 1 not taken.
192390 if(fallclk > 0)
3112 {
3113 if(fallclk == PITFALL_FALL_FRAMES && fallCombo) sfx(combobuf[fallCombo].attribytes[0], pan(x.getInt()));
3114 if(!--fallclk)
3115 {
3116 if(immortal) //Keep alive forever
3117 ++fallclk; //force another frame of falling.... forever.
3118 else if(dying) //Give 1 frame for script revival
3119 {
3120 if(flags&guy_neverret)
3121 never_return(index);
3122
3123 if(leader)
3124 kill_em_all();
3125
3126 //leave_item(); //Don't drop items in pits!
3127 stop_bgsfx(index);
3128 return true;
3129 }
3130 else
3131 {
3132 try_death(true); //Force death
3133 ++fallclk; //force another frame of falling
3134 }
3135 }
3136
3137 wpndata& spr = wpnsbuf[QMisc.sprites[sprFALL]];
3138 cs = spr.csets & 0xF;
3139 int32_t fr = spr.frames ? spr.frames : 1;
3140 int32_t spd = spr.speed ? spr.speed : 1;
3141 int32_t animclk = (PITFALL_FALL_FRAMES-fallclk);
3142 tile = spr.tile + zc_min(animclk / spd, fr-1);
3143 }
3144 192390 return false;
3145 192390 }
3146
3147 // Handle drowning in water
3148 192390 bool enemy::do_drowning(int32_t index)
3149 {
3150
1/2
✓ Branch 0 taken 192390 times.
✗ Branch 1 not taken.
192390 if(drownclk > 0)
3151 {
3152 //if(drownclk == WATER_DROWN_FRAMES && drownCombo) sfx(combobuf[drownCombo].attribytes[0], pan(x.getInt()));
3153 //!TODO: Drown SFX
3154 if(!--drownclk)
3155 {
3156 if(immortal) //Keep alive forever
3157 ++drownclk; //force another frame of falling.... forever.
3158 else if(dying) //Give 1 frame for script revival
3159 {
3160 if(flags&guy_neverret)
3161 never_return(index);
3162
3163 if(leader)
3164 kill_em_all();
3165
3166 //leave_item(); //Don't drop items in pits!
3167 stop_bgsfx(index);
3168 return true;
3169 }
3170 else
3171 {
3172 try_death(true); //Force death
3173 ++drownclk; //force another frame of falling
3174 }
3175 }
3176
3177 if (drownCombo && combobuf[drownCombo].usrflags&cflag1)
3178 {
3179 wpndata &spr = wpnsbuf[QMisc.sprites[sprLAVADROWN]];
3180 cs = spr.csets & 0xF;
3181 int32_t fr = spr.frames ? spr.frames : 1;
3182 int32_t spd = spr.speed ? spr.speed : 1;
3183 int32_t animclk = (WATER_DROWN_FRAMES-drownclk);
3184 tile = spr.tile + zc_min((animclk % (spd*fr))/spd, fr-1);
3185 }
3186 else
3187 {
3188 wpndata &spr = wpnsbuf[QMisc.sprites[sprDROWN]];
3189 cs = spr.csets & 0xF;
3190 int32_t fr = spr.frames ? spr.frames : 1;
3191 int32_t spd = spr.speed ? spr.speed : 1;
3192 int32_t animclk = (WATER_DROWN_FRAMES-drownclk);
3193 tile = spr.tile + zc_min((animclk % (spd*fr))/spd, fr-1);
3194 }
3195 }
3196 192390 return false;
3197 192390 }
3198
3199 // Supplemental animation code that all derived classes should call
3200 // as a return value for animate().
3201 // Handles the death animation and returns true when enemy is finished.
3202 196841 bool enemy::Dead(int32_t index)
3203 {
3204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 196841 times.
196841 if(immortal)
3205 {
3206 dying = false;
3207 return false;
3208 }
3209
2/2
✓ Branch 0 taken 4699 times.
✓ Branch 1 taken 192142 times.
196841 if(dying)
3210 {
3211
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4699 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4699 if(deathexstate > -1 && deathexstate < 32)
3212 {
3213 setxmapflag(1<<deathexstate);
3214 deathexstate = -1;
3215 }
3216 4699 --clk2;
3217
3218
2/4
✓ Branch 0 taken 4699 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 247 times.
✗ Branch 3 not taken.
4699 if((get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS) && clk2==12)
3219
2/2
✓ Branch 0 taken 247 times.
✓ Branch 1 taken 4452 times.
4699 && hp>-1000) // not killed by ringleader
3220 247 death_sfx();
3221
3222
2/2
✓ Branch 0 taken 4452 times.
✓ Branch 1 taken 247 times.
4699 if(clk2==0)
3223 {
3224
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 2 times.
247 if(flags&guy_neverret)
3225 2 never_return(index);
3226
3227
1/2
✓ Branch 0 taken 247 times.
✗ Branch 1 not taken.
247 if(leader)
3228 kill_em_all();
3229
3230 247 leave_item();
3231 247 }
3232
3233 4699 stop_bgsfx(index);
3234 4699 return (clk2==0);
3235 }
3236
3237 192142 return false;
3238 196841 }
3239
3240 // Basic animation code that all derived classes should call.
3241 // The one with an index is the one that is called by
3242 // the guys sprite list; index is the enemy's index in the list.
3243 200646 bool enemy::animate(int32_t index)
3244 {
3245
2/2
✓ Branch 0 taken 9900 times.
✓ Branch 1 taken 190746 times.
200646 if(sclk <= 0) hitdir = -1;
3246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200646 times.
200646 if(switch_hooked)
3247 {
3248 if(get_bit(quest_rules, qr_SWITCHOBJ_RUN_SCRIPT))
3249 {
3250 //Run its script
3251 if (run_script(MODE_NORMAL)==RUNSCRIPT_SELFDELETE)
3252 {
3253 return 0; //Avoid NULLPO if this object deleted itself
3254 }
3255 }
3256 return false;
3257 }
3258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200646 times.
200646 if(do_falling(index)) return true;
3259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200646 times.
200646 else if(fallclk)
3260 {
3261 //clks
3262 if(hclk>0)
3263 --hclk;
3264 if(stunclk>0)
3265 --stunclk;
3266 if ( frozenclock > 0 )
3267 --frozenclock;
3268 if(hashero)
3269 {
3270 Hero.setX(x);
3271 Hero.setY(y);
3272 Hero.fallCombo = fallCombo;
3273 Hero.fallclk = fallclk;
3274 hashero = false; //Let Hero go if falling
3275 }
3276 run_script(MODE_NORMAL);
3277 return false;
3278 }
3279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200646 times.
200646 if(do_drowning(index)) return true;
3280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200646 times.
200646 else if(drownclk)
3281 {
3282 //clks
3283 if(hclk>0)
3284 --hclk;
3285 if(stunclk>0)
3286 --stunclk;
3287 if ( frozenclock > 0 )
3288 --frozenclock;
3289 if(hashero)
3290 {
3291 Hero.setX(x);
3292 Hero.setY(y);
3293 Hero.drownclk = drownclk;
3294 hashero = false; //Let Hero go if falling
3295 }
3296 run_script(MODE_NORMAL);
3297 return false;
3298 }
3299 200646 int32_t nx = real_x(x);
3300 200646 int32_t ny = real_y(y);
3301
3302
4/4
✓ Branch 0 taken 137399 times.
✓ Branch 1 taken 63247 times.
✓ Branch 2 taken 21682 times.
✓ Branch 3 taken 159081 times.
200646 if(ox!=nx || oy!=ny)
3303 {
3304 84929 posframe=(posframe+1)%(get_bit(quest_rules,qr_NEWENEMYTILES)?4:2);
3305 84929 }
3306
3307 244010 ox = nx;
3308 244010 oy = ny;
3309
3310 // Maybe they fell off the bottom in sideview, or were moved by a script.
3311
3312 //Check offscreen settings. I wrote it this way for clarity and to simplify testing. -Z
3313
2/2
✓ Branch 0 taken 51620 times.
✓ Branch 1 taken 192390 times.
244010 if ( immortal )
3314 {
3315 //skip, as it can go out of bounds, from immortality
3316 51620 }
3317
2/6
✓ Branch 0 taken 192390 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 192390 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
192390 else if ( (moveflags & FLAG_IGNORE_SCREENEDGE) || (( (get_bit(quest_rules, qr_OUTOFBOUNDSENEMIES)) != (editorflags&ENEMY_FLAG11) ) && !NEWOUTOFBOUNDS(x,y,z+fakez)) )
3318 {
3319 //skip, it can go out of bounds, from a quest rule, or from the enemy editor (but not both!)
3320 }
3321
6/10
✓ Branch 0 taken 168090 times.
✓ Branch 1 taken 24300 times.
✓ Branch 2 taken 192390 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 192390 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 192390 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 192390 times.
192390 else if ( (OUTOFBOUNDS) )
3322 {
3323 hp=-1000; //kill it, as it is not immortal, and no quest bit or rule is enabled
3324 }
3325 //fall down
3326
6/6
✓ Branch 0 taken 50607 times.
✓ Branch 1 taken 193403 times.
✓ Branch 2 taken 141783 times.
✓ Branch 3 taken 102227 times.
✓ Branch 4 taken 6154 times.
✓ Branch 5 taken 135629 times.
244010 if((enemycanfall(id) || (moveflags & FLAG_OBEYS_GRAV) )&& fading != fade_flicker && clk>=0)
3327 {
3328
2/2
✓ Branch 0 taken 24000 times.
✓ Branch 1 taken 111629 times.
135629 if(isSideViewGravity())
3329 {
3330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24000 times.
24000 if(get_bit(quest_rules,qr_OLD_SIDEVIEW_LANDING_CODE))
3331 {
3332 if(!isOnSideviewPlatform())
3333 {
3334 bool willHitSVPlatform = false;
3335 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH)?hxsz:16;
3336 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT)?hysz:16;
3337 for(int32_t nx = x+4; nx < x+usewid; nx+=16)
3338 {
3339 if(fall > 0 && !IGNORE_SIDEVIEW_PLATFORMS && checkSVLadderPlatform(x+4,y+(fall/100)+usehei-1) && (((int32_t(y)+(int32_t(fall)/100)+usehei-1)&0xF0)!=((int32_t(y)+usehei-1)&0xF0)))
3340 {
3341 willHitSVPlatform = true;
3342 break;
3343 }
3344 }
3345 if(willHitSVPlatform)
3346 {
3347 y+=fall/100;
3348 //y-=int32_t(y)%16; //Fix to top of SV Ladder
3349 do_fix(y, 16); //Fix to top of SV Ladder
3350 fall = 0;
3351 }
3352 else
3353 {
3354 y+=fall/100;
3355 if(fall <= (int32_t)zinit.terminalv)
3356 fall += (zinit.gravity2/100);
3357 }
3358 }
3359 else
3360 {
3361 if(fall!=0) // Only fix pos once
3362 {
3363 //y-=(int32_t)y%8; // Fix position
3364 do_fix(y, 8); //Fix position
3365 }
3366
3367 fall = 0;
3368 }
3369 }
3370 else
3371 {
3372
2/2
✓ Branch 0 taken 22585 times.
✓ Branch 1 taken 1415 times.
24000 if(isOnSideviewPlatform())
3373 22585 fall = 0;
3374 else
3375 {
3376 1415 zfix fall_amnt = fall/100;
3377 1415 bool hit = false;
3378
2/2
✓ Branch 0 taken 1382 times.
✓ Branch 1 taken 1819 times.
3201 while(fall_amnt >= 1)
3379 {
3380 1819 --fall_amnt;
3381 1819 ++y;
3382
2/2
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 33 times.
1819 if(isOnSideviewPlatform())
3383 {
3384 33 y = y.getInt();
3385 33 fall_amnt = 0;
3386 33 hit = true;
3387 33 break;
3388 }
3389 }
3390
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 1302 times.
1415 if(fall_amnt > 0)
3391 1302 y += fall_amnt;
3392
1/2
✓ Branch 0 taken 1415 times.
✗ Branch 1 not taken.
1415 if(fall_amnt < 0)
3393 {
3394 if(!movexy(0,fall_amnt,spw_none))
3395 hit = true;
3396 }
3397
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 1382 times.
1415 if(hit)
3398 33 fall = 0;
3399
2/2
✓ Branch 0 taken 277 times.
✓ Branch 1 taken 1105 times.
1382 else if(fall <= (int32_t)zinit.terminalv)
3400 1105 fall += (zinit.gravity2/100);
3401 }
3402 }
3403 24000 }
3404 else
3405 {
3406
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 111629 times.
111629 if (!(moveflags & FLAG_NO_FAKE_Z))
3407 {
3408
2/2
✓ Branch 0 taken 74727 times.
✓ Branch 1 taken 36902 times.
111629 if(fakefall!=0)
3409 36902 fakez-=(fakefall/100);
3410
3411
2/2
✓ Branch 0 taken 36902 times.
✓ Branch 1 taken 74727 times.
111629 if(fakez<0)
3412 36902 fakez = fakefall = 0;
3413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74727 times.
74727 else if(fakefall <= (int32_t)zinit.terminalv)
3414 74727 fakefall += (zinit.gravity2/100);
3415
3416
5/6
✓ Branch 0 taken 111629 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74727 times.
✓ Branch 3 taken 36902 times.
✓ Branch 4 taken 37010 times.
✓ Branch 5 taken 37717 times.
111629 if (fakez<=0 && fakefall > 0 && !get_bit(quest_rules, qr_FLUCTUATING_ENEMY_JUMP)) fakefall = 0;
3417 111629 }
3418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 111629 times.
111629 if (!(moveflags & FLAG_NO_REAL_Z))
3419 {
3420
2/2
✓ Branch 0 taken 74727 times.
✓ Branch 1 taken 36902 times.
111629 if(fall!=0)
3421 36902 z-=(fall/100);
3422
3423
2/2
✓ Branch 0 taken 36902 times.
✓ Branch 1 taken 74727 times.
111629 if(z<0)
3424 36902 z = fall = 0;
3425
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74727 times.
74727 else if(fall <= (int32_t)zinit.terminalv)
3426 74727 fall += (zinit.gravity2/100);
3427
3428
5/6
✓ Branch 0 taken 111629 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74727 times.
✓ Branch 3 taken 36902 times.
✓ Branch 4 taken 37010 times.
✓ Branch 5 taken 37717 times.
111629 if (z<=0 && fall > 0 && !get_bit(quest_rules, qr_FLUCTUATING_ENEMY_JUMP)) fall = 0;
3429 111629 }
3430
3431 }
3432 135629 }
3433
4/4
✓ Branch 0 taken 168090 times.
✓ Branch 1 taken 75920 times.
✓ Branch 2 taken 158247 times.
✓ Branch 3 taken 326337 times.
244010 if(!isSideViewGravity() && (moveflags & FLAG_CAN_PITFALL))
3434 {
3435
7/10
✓ Branch 0 taken 109100 times.
✓ Branch 1 taken 217237 times.
✓ Branch 2 taken 109100 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 109100 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 109100 times.
✓ Branch 8 taken 109100 times.
✓ Branch 9 taken 109100 times.
326337 if(can_pitfall() && ((z <= 0 && fakez <= 0 && !isflier(id)) || (isflier(id) && (stunclk))) && !superman)
3436 {
3437 109100 fallCombo = check_pits();
3438 109100 }
3439 544537 }
3440
3/4
✓ Branch 0 taken 168090 times.
✓ Branch 1 taken 24300 times.
✓ Branch 2 taken 168090 times.
✗ Branch 3 not taken.
344230 if(!isSideViewGravity() && (moveflags & FLAG_CAN_WATERDROWN))
3441 {
3442 if(can_pitfall() && ((z <= 0 && fakez <= 0 && !isflier(id)) || (isflier(id) && (stunclk))) && !superman)
3443 {
3444 drownCombo = check_water();
3445 }
3446 }
3447
3448 192390 runKnockback(); //scripted knockback handling
3449
3450 // clk is incremented here
3451
2/2
✓ Branch 0 taken 180699 times.
✓ Branch 1 taken 11691 times.
192390 if(++clk >= frate)
3452 11691 clk=0;
3453
3454 // hit and death handling
3455
2/2
✓ Branch 0 taken 187657 times.
✓ Branch 1 taken 4733 times.
192390 if(hclk>0)
3456 4733 --hclk;
3457
3458
2/2
✓ Branch 0 taken 187526 times.
✓ Branch 1 taken 4864 times.
192390 if(stunclk>0)
3459 4864 --stunclk;
3460
1/2
✓ Branch 0 taken 192390 times.
✗ Branch 1 not taken.
192390 if ( frozenclock > 0 )
3461 --frozenclock;
3462
3463
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 192390 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
192390 if(ceiling && z <= 0 && fakez <= 0)
3464 ceiling = false;
3465
3466 192390 try_death();
3467
3468 192390 scored=false;
3469
3470 192390 ++c_clk;
3471
3472 //Run its script
3473
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 192390 times.
192390 if (run_script(MODE_NORMAL)==RUNSCRIPT_SELFDELETE)
3474 {
3475 return 0; //Avoid NULLPO if this object deleted itself
3476 }
3477
3478 // returns true when enemy is defeated
3479 192390 return Dead(index);
3480 192390 }
3481
3482 196594 bool enemy::setSolid(bool set)
3483 {
3484
1/2
✓ Branch 0 taken 196594 times.
✗ Branch 1 not taken.
196594 bool actual = set && !isSubmerged();
3485 196594 bool ret = solid_object::setSolid(actual);
3486 196594 solid = set;
3487 196594 return ret;
3488 }
3489 void enemy::doContactDamage(int32_t hdir)
3490 {
3491 Hero.hithero(guys.find(this), hdir);
3492 }
3493
3494 87210 void enemy::solid_push(solid_object *obj)
3495 {
3496
1/2
✓ Branch 0 taken 87210 times.
✗ Branch 1 not taken.
87210 if(obj == this) return; //can't push self
3497
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 87210 times.
87210 if(moveflags&FLAG_NOT_PUSHABLE) return; //not pushable
3498 87210 zfix dx, dy;
3499 87210 int32_t hdir = -1;
3500 87210 solid_push_int(obj,dx,dy,hdir);
3501
3502
4/4
✓ Branch 0 taken 85854 times.
✓ Branch 1 taken 1356 times.
✓ Branch 2 taken 83962 times.
✓ Branch 3 taken 1892 times.
87210 if(!dx && !dy) return;
3503
3504 3248 bool t = obj->getTempNonsolid();
3505 3248 obj->setTempNonsolid(true);
3506
3507 3248 int32_t ydir = dy > 0 ? down : up;
3508 3248 int32_t xdir = dx > 0 ? right : left;
3509
3510 3248 auto special = isflier(id) ? spw_floater : spw_none;
3511
2/2
✓ Branch 0 taken 2905 times.
✓ Branch 1 taken 343 times.
3248 if(!movexy(dx,dy,special,true,true))
3512 {
3513 //Crushed?
3514 343 }
3515
3516 3248 obj->setTempNonsolid(t);
3517 87210 }
3518 87210 bool enemy::is_unpushable() const
3519 {
3520 87210 return isSubmerged();
3521 }
3522 87210 bool enemy::sideview_mode() const
3523 {
3524
3/4
✓ Branch 0 taken 24300 times.
✓ Branch 1 taken 62910 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24300 times.
87210 return isSideViewGravity() && (moveflags&FLAG_OBEYS_GRAV) && !(moveflags&FLAG_NOT_PUSHABLE);
3525 }
3526
3527 bool enemy::m_walkflag_old(int32_t dx,int32_t dy,int32_t special, int32_t x, int32_t y)
3528 {
3529 int32_t yg = (special==spw_floater)?8:0;
3530 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
3531
3532 if(dx<16-nb || dy<zc_max(16-yg-nb,0) || dx>=240+nb || dy>=160+nb)
3533 return true;
3534
3535 bool isInDungeon = isdungeon();
3536 if(isInDungeon || special==spw_wizzrobe)
3537 {
3538 if((x>=32 && dy<32-yg) || (y>-1000 && y<=144 && dy>=144))
3539 return true;
3540
3541 if((x>=32 && dx<32) || (x>-1000 && x<224 && dx>=224))
3542 if(special!=spw_door) // walk in door way
3543 return true;
3544 }
3545
3546 if(!(moveflags & FLAG_CAN_PITWALK) && !(moveflags & FLAG_CAN_PITFALL)) //Don't walk into pits (knockback doesn't call this func)
3547 {
3548 if(ispitfall(dx,dy) || ispitfall(dx+8,dy)
3549 || ispitfall(dx,dy+8) || ispitfall(dx+8,dy+8))
3550 return true;
3551 }
3552
3553 switch(special)
3554 {
3555 case spw_clipbottomright:
3556 if(dy>=128 || dx>=208) return true;
3557 break;
3558 case spw_clipright:
3559 break; //if(x>=208) return true; break;
3560
3561 case spw_wizzrobe: // fall through
3562 case spw_floater: // Special case for fliers and wizzrobes - hack!
3563 {
3564 if(isInDungeon)
3565 {
3566 if(dy < 32-yg || dy >= 144) return true;
3567 if(dx < 32 || dx >= 224) return true;
3568 }
3569 return false;
3570 }
3571 }
3572
3573 dx&=(special==spw_halfstep)?(~7):(~15);
3574 dy&=(special==spw_halfstep || isSideViewGravity())?(~7):(~15);
3575
3576 if(special==spw_water)
3577 return (water_walkflag(dx,dy+8,1) || water_walkflag(dx+8,dy+8,1));
3578
3579 return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3580 groundblocked(dx,dy+8) || groundblocked(dx+8,dy+8);
3581 }
3582
3583 bool enemy::m_walkflag_simple(int32_t dx,int32_t dy)
3584 {
3585 bool kb = false;
3586 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
3587
3588 if(dx<16-nb || dy<zc_max(16-nb,0) || dx>=240+nb || dy>=160+nb)
3589 return true;
3590
3591 if(isdungeon())
3592 {
3593 if((dy<32) || (dy>=144))
3594 return true;
3595
3596 if((dx<32) || (dx>=224))
3597 return true;
3598 }
3599
3600 if(!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL))) //Don't walk into pits, unless being knocked back
3601 {
3602 if(ispitfall(dx,dy) || ispitfall(dx+8,dy)
3603 || ispitfall(dx,dy+8) || ispitfall(dx+8,dy+8))
3604 return true;
3605 }
3606
3607 if(get_bit(quest_rules,qr_ENEMY_BROKEN_TOP_HALF_SOLIDITY))
3608 {
3609 return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3610 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3611 }
3612 else
3613 {
3614 return _walkflag(dx,dy,1) || _walkflag(dx+8,dy,1) ||
3615 _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3616 groundblocked(dx,dy,kb) || groundblocked(dx+8,dy,kb) ||
3617 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3618 }
3619 }
3620
3621 222671 bool enemy::m_walkflag(int32_t dx,int32_t dy,int32_t special, int32_t dir, int32_t input_x, int32_t input_y, bool kb)
3622 {
3623
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 222671 times.
222671 if(moveflags & FLAG_USE_NEW_MOVEMENT)
3624 return scr_walkflag(dx,dy,special,dir,input_x,input_y,kb);
3625 222671 int32_t yg = (special==spw_floater)?8:0;
3626 222671 int32_t nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
3627
2/2
✓ Branch 0 taken 21481 times.
✓ Branch 1 taken 201190 times.
222671 switch(dir)
3628 {
3629 case l_down:
3630 case r_down:
3631 case down:
3632 case 11: //r_down
3633 case 12: //down
3634 case 13: //l_down
3635 {
3636
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21481 times.
21481 if ( ((unsigned)(id&0xFFF)) < MAXGUYS )
3637 {
3638
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 21481 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
21481 if ( SIZEflags&guyflagOVERRIDE_HIT_HEIGHT && !isflier(id) )
3639 {
3640 //Small enemies are treated as 16x16, for the purposes of m_walkflag!
3641 dy += zc_max(hysz-16,0);
3642 }
3643 21481 }
3644 21481 break;
3645 }
3646 }
3647
2/2
✓ Branch 0 taken 20928 times.
✓ Branch 1 taken 201743 times.
222671 switch(dir)
3648 {
3649 case r_up:
3650 case r_down:
3651 case right:
3652 case 9: //r_up
3653 case 10: //right
3654 case 11: //r_down
3655 {
3656
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20928 times.
20928 if ( ((unsigned)(id&0xFFF)) < MAXGUYS )
3657 {
3658
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 20928 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
20928 if ( SIZEflags&guyflagOVERRIDE_HIT_WIDTH && !isflier(id) )
3659 {
3660 //Small enemies are treated as 16x16, for the purposes of m_walkflag!
3661 dx += zc_max(hxsz-16,0);
3662 }
3663 20928 }
3664 20928 break;
3665 }
3666 }
3667 //Z_eventlog("Checking x,y %d,%d\n",dx,dy);
3668
3669
10/10
✓ Branch 0 taken 173094 times.
✓ Branch 1 taken 49577 times.
✓ Branch 2 taken 24882 times.
✓ Branch 3 taken 24695 times.
✓ Branch 4 taken 49471 times.
✓ Branch 5 taken 106 times.
✓ Branch 6 taken 49233 times.
✓ Branch 7 taken 238 times.
✓ Branch 8 taken 173457 times.
✓ Branch 9 taken 222690 times.
222671 if(dx<16-nb || dy<zc_max(16-yg-nb,0) || dx>=240+nb || dy>=160+nb)
3670 346895 return true;
3671
3672 222690 bool isInDungeon = isdungeon();
3673
3/4
✓ Branch 0 taken 4796 times.
✓ Branch 1 taken 217894 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4796 times.
222690 if(isInDungeon || special==spw_wizzrobe)
3674 {
3675
8/8
✓ Branch 0 taken 44314 times.
✓ Branch 1 taken 173580 times.
✓ Branch 2 taken 43450 times.
✓ Branch 3 taken 864 times.
✓ Branch 4 taken 44050 times.
✓ Branch 5 taken 130394 times.
✓ Branch 6 taken 44049 times.
✓ Branch 7 taken 1 times.
217894 if((input_x>=32 && dy<32-yg) || (input_y>-1000 && input_y<=144 && dy>=144))
3676 87499 return true;
3677
3678
7/8
✓ Branch 0 taken 43716 times.
✓ Branch 1 taken 86679 times.
✓ Branch 2 taken 43331 times.
✓ Branch 3 taken 385 times.
✓ Branch 4 taken 43634 times.
✓ Branch 5 taken 43430 times.
✓ Branch 6 taken 43634 times.
✗ Branch 7 not taken.
130395 if((input_x>=32 && dx<32) || (input_x>-1000 && input_x<224 && dx>=224))
3679
1/2
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
86965 if(special!=spw_door) // walk in door way
3680 303 return true;
3681 43430 }
3682
3683
5/6
✓ Branch 0 taken 6779 times.
✓ Branch 1 taken 41447 times.
✓ Branch 2 taken 6779 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 610 times.
✓ Branch 5 taken 6169 times.
48226 if(!(moveflags & FLAG_CAN_PITWALK) && (!(moveflags & FLAG_CAN_PITFALL) || !kb)) //Don't walk into pits, unless being knocked back
3684 {
3685
2/4
✓ Branch 0 taken 6169 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6169 times.
12338 if(ispitfall(dx,dy) || ispitfall(dx+8,dy)
3686
2/4
✓ Branch 0 taken 6169 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6169 times.
✗ Branch 3 not taken.
6169 || ispitfall(dx,dy+8) || ispitfall(dx+8,dy+8))
3687 return true;
3688 6169 }
3689
3690
3/4
✓ Branch 0 taken 41429 times.
✓ Branch 1 taken 6795 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
48226 switch(special)
3691 {
3692 case spw_clipbottomright:
3693 if(dy>=128 || dx>=208) return true;
3694 break;
3695 case spw_clipright:
3696 2 break; //if(input_x>=208) return true; break;
3697
3698 case spw_wizzrobe: // fall through
3699 case spw_floater: // Special case for fliers and wizzrobes - hack!
3700 {
3701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41429 times.
41429 if(isInDungeon)
3702 {
3703
2/4
✓ Branch 0 taken 41429 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 41429 times.
41429 if(dy < 32-yg || dy >= 144) return true;
3704
3/4
✓ Branch 0 taken 41419 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 41419 times.
41429 if(dx < 32 || dx >= 224) return true;
3705 41419 }
3706 41419 return false;
3707 }
3708 }
3709
3710 6797 dx&=(special==spw_halfstep)?(~7):(~15);
3711
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6791 times.
6797 dy&=(special==spw_halfstep || isSideViewGravity())?(~7):(~15);
3712
3713
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6797 times.
6797 if(special==spw_water)
3714 return (water_walkflag(dx,dy+8,1) || water_walkflag(dx+8,dy+8,1));
3715
3716
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 3101 times.
6797 if(get_bit(quest_rules,qr_ENEMY_BROKEN_TOP_HALF_SOLIDITY))
3717 {
3718
4/4
✓ Branch 0 taken 2835 times.
✓ Branch 1 taken 861 times.
✓ Branch 2 taken 2776 times.
✓ Branch 3 taken 59 times.
6472 return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3719
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2776 times.
2776 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3720 }
3721 else
3722 {
3723
4/4
✓ Branch 0 taken 2716 times.
✓ Branch 1 taken 385 times.
✓ Branch 2 taken 2620 times.
✓ Branch 3 taken 96 times.
5721 return _walkflag(dx,dy,1) || _walkflag(dx+8,dy,1) ||
3724
4/4
✓ Branch 0 taken 2501 times.
✓ Branch 1 taken 119 times.
✓ Branch 2 taken 2488 times.
✓ Branch 3 taken 13 times.
2620 _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
3725
3/4
✓ Branch 0 taken 2438 times.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 2438 times.
✗ Branch 3 not taken.
2488 groundblocked(dx,dy,kb) || groundblocked(dx+8,dy,kb) ||
3726
1/2
✓ Branch 0 taken 2438 times.
✗ Branch 1 not taken.
2438 groundblocked(dx,dy+8,kb) || groundblocked(dx+8,dy+8,kb);
3727 }
3728 49835 }
3729
3730 40823 bool enemy::isOnSideviewPlatform()
3731 {
3732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40823 times.
40823 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
3733
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40823 times.
40823 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
3734
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 40823 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
40823 if(y + usehei >= 176 && currscr>=0x70 && !(tmpscr->flags2&wfDOWN)) return true; //Bottom of the map
3735
2/2
✓ Branch 0 taken 2205 times.
✓ Branch 1 taken 38618 times.
40823 if(check_slope(x, y+1, usewid, usehei)) return true;
3736
2/2
✓ Branch 0 taken 38618 times.
✓ Branch 1 taken 4373 times.
42991 for(int32_t nx = x + 4; nx <= x + usewid - 4; nx+=16)
3737 {
3738
2/2
✓ Branch 0 taken 4373 times.
✓ Branch 1 taken 34245 times.
38618 if(_walkflag(nx,y+usehei,1)) return true;
3739
3/4
✓ Branch 0 taken 4373 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3971 times.
✓ Branch 3 taken 402 times.
4373 if(IGNORE_SIDEVIEW_PLATFORMS || ((int32_t(y)+usehei)%16)!=0) continue;
3740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 402 times.
402 if(checkSVLadderPlatform(nx,y+usehei)) return true;
3741 402 }
3742 4373 return false;
3743 40823 }
3744
3745 // Stops playing the given sound only if there are no enemies left to play it
3746 4699 void enemy::stop_bgsfx(int32_t index)
3747 {
3748
2/2
✓ Branch 0 taken 4661 times.
✓ Branch 1 taken 38 times.
4699 if(bgsfx<=0)
3749 4661 return;
3750
3751 // Look for other enemies with the same bgsfx
3752
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 38 times.
76 for(int32_t i=0; i<guys.Count(); i++)
3753 {
3754
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
38 if(i!=index && ((enemy*)guys.spr(i))->bgsfx==bgsfx)
3755 return;
3756 38 }
3757
3758 38 stop_sfx(bgsfx);
3759 4699 }
3760
3761
3762 // to allow for different sfx on defeating enemy
3763 247 void enemy::death_sfx()
3764 {
3765
1/2
✓ Branch 0 taken 247 times.
✗ Branch 1 not taken.
247 if(deadsfx > 0) sfx(deadsfx,pan(int32_t(x)));
3766 247 }
3767
3768 void enemy::move(zfix dx,zfix dy)
3769 {
3770 /*if(FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && FFCore.getQuestHeaderInfo(vBuild) >= 50 )
3771 {
3772 switch(family)
3773 {
3774 case eeFIRE:
3775 case eeOTHER:
3776 return;
3777 default: break;
3778 }
3779 if(family >= eeSCRIPT01 && family <= eeFFRIENDLY10 ) return;
3780 }
3781 */
3782 if(!watch && (!(isSideViewGravity()) || isOnSideviewPlatform() || !(moveflags & FLAG_OBEYS_GRAV) || !enemycanfall(id)))
3783 {
3784 x+=dx;
3785 y+=dy;
3786 }
3787 }
3788
3789 112509 void enemy::move(zfix s)
3790 {
3791 /*if(FFCore.getQuestHeaderInfo(vZelda) >= 0x255 && FFCore.getQuestHeaderInfo(vBuild) >= 50 )
3792 {
3793 switch(family)
3794 {
3795 case eeFIRE:
3796 case eeOTHER:
3797 return;
3798 default: break;
3799 }
3800 if(family >= eeSCRIPT01 && family <= eeFFRIENDLY10 ) return;
3801 }*/
3802
7/10
✓ Branch 0 taken 112509 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15004 times.
✓ Branch 3 taken 97505 times.
✓ Branch 4 taken 1172 times.
✓ Branch 5 taken 13832 times.
✓ Branch 6 taken 1172 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1172 times.
✗ Branch 9 not taken.
112509 if(!watch && (!(isSideViewGravity()) || isOnSideviewPlatform() || !enemycanfall(id) || !(moveflags & FLAG_OBEYS_GRAV)))
3803 {
3804 111337 sprite::move(s);
3805 111337 }
3806 112509 }
3807
3808 247 void enemy::leave_item()
3809 {
3810 247 int32_t drop_item = select_dropitem(item_set, x, y);
3811 247 int32_t thedropset = item_set;
3812
3813 247 std::vector<int32_t> &ev = FFCore.eventData;
3814 247 ev.clear();
3815 247 ev.push_back(getUID());
3816 247 ev.push_back(drop_item*10000);
3817 247 ev.push_back(thedropset*10000);
3818
3819 247 throwGenScriptEvent(GENSCR_EVENT_ENEMY_DROP_ITEM_1);
3820 247 drop_item = vbound(ev[1] / 10000,-2,255);
3821 247 thedropset = ev[2] / 10000;
3822 247 ev.clear();
3823
1/2
✓ Branch 0 taken 247 times.
✗ Branch 1 not taken.
247 if(drop_item == -2)
3824 {
3825 drop_item = select_dropitem(thedropset,x,y);
3826 }
3827
3828
3/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 157 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 90 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
247 if(drop_item>=0&&((itemsbuf[drop_item].family!=itype_fairy)||!m_walkflag(x,y,0,dir)))
3829 {
3830 item* itm;
3831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
90 if (get_bit(quest_rules, qr_ENEMY_DROPS_USE_HITOFFSETS))
3832 {
3833 itm = (new item(x+hxofs+(hxsz/2)-8,y+hyofs+(hysz/2)-8,(zfix)0,drop_item,ipBIGRANGE+ipTIMER,0));
3834 }
3835 else
3836 {
3837
1/14
✗ Branch 0 not taken.
✓ Branch 1 taken 90 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
90 if(extend >= 3) itm = (new item(x+(txsz-1)*8,y+(tysz-1)*8,(zfix)0,drop_item,ipBIGRANGE+ipTIMER,0));
3838
4/8
✓ Branch 0 taken 90 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 90 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 90 times.
✗ Branch 7 not taken.
90 else itm = (new item(x,y,(zfix)0,drop_item,ipBIGRANGE+ipTIMER,0));
3839 }
3840 90 itm->from_dropset = thedropset;
3841 90 items.add(itm);
3842
3843 90 ev.push_back(getUID());
3844 90 ev.push_back(itm->getUID());
3845
3846 90 throwGenScriptEvent(GENSCR_EVENT_ENEMY_DROP_ITEM_2);
3847 90 ev.clear();
3848 90 }
3849 247 }
3850
3851 // auomatically kill off enemy (for rooms with ringleaders)
3852 void enemy::kickbucket()
3853 {
3854 if(!superman)
3855 hp=-1000; // don't call death_sfx()
3856 }
3857
3858 87210 bool enemy::isSubmerged() const
3859 {
3860 87210 return submerged;
3861 //!TODO SOLIDPUSH more things like teleporting wizzrobes
3862 }
3863
3864 void enemy::FireBreath(bool seekhero)
3865 {
3866 if(wpn==wNone)
3867 return;
3868
3869 if(wpn==ewFireTrail)
3870 {
3871 dmisc1 = e1tEACHTILE;
3872 FireWeapon();
3873 return;
3874 }
3875
3876 float fire_angle=0.0;
3877 int32_t wx=0, wy=0, wdir=dir;
3878
3879 if(!seekhero)
3880 {
3881 switch(dir)
3882 {
3883 case down:
3884 fire_angle=PI*(int64_t(zc_oldrand()%20)+10)/40;
3885 wx=x;
3886 wy=y+8;
3887 break;
3888
3889 case -1:
3890 case up:
3891 fire_angle=PI*(int64_t(zc_oldrand()%20)+50)/40;
3892 wx=x;
3893 wy=y-8;
3894 break;
3895
3896 case left:
3897 fire_angle=PI*(int64_t(zc_oldrand()%20)+30)/40;
3898 wx=x-8;
3899 wy=y;
3900 break;
3901
3902 case right:
3903 fire_angle=PI*(int64_t(zc_oldrand()%20)+70)/40;
3904 wx=x+8;
3905 wy=y;
3906 break;
3907 }
3908
3909 if(wpn==ewFlame || wpn==ewFlame2)
3910 {
3911 if(fire_angle==-PI || fire_angle==PI) wdir=left;
3912 else if(fire_angle==-PI/2) wdir=up;
3913 else if(fire_angle==PI/2) wdir=down;
3914 else if(fire_angle==0) wdir=right;
3915 else if(fire_angle<-PI/2) wdir=l_up;
3916 else if(fire_angle<0) wdir=r_up;
3917 else if(fire_angle<(PI/2)) wdir=r_down;
3918 else if(fire_angle<PI) wdir=l_down;
3919 }
3920 }
3921 else
3922 {
3923 wx = x;
3924 wy = y;
3925 }
3926
3927 addEwpn(wx,wy,z,wpn,2,wdp,seekhero ? 0xFF : wdir, getUID(), 0, fakez);
3928 sfx(wpnsfx(wpn),pan(int32_t(x)));
3929
3930 int32_t i=Ewpns.Count()-1;
3931 weapon *ew = (weapon*)(Ewpns.spr(i));
3932 ew->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
3933
3934 if(!seekhero && (zc_oldrand()&4))
3935 {
3936 ew->angular=true;
3937 ew->angle=fire_angle;
3938 }
3939
3940 if(wpn==ewFlame && wpnsbuf[ewFLAME].frames>1)
3941 {
3942 ew->aframe=zc_oldrand()%wpnsbuf[ewFLAME].frames;
3943 if ( ew->do_animation ) ew->tile+=ew->aframe;
3944 }
3945
3946 for(int32_t j=Ewpns.Count()-1; j>0; j--)
3947 {
3948 Ewpns.swap(j,j-1);
3949 }
3950 }
3951
3952 189 void enemy::FireWeapon()
3953 {
3954 /*
3955 * Type:
3956 * 0x01: Boss fireball
3957 * 0x02: Seeks Hero
3958 * 0x04: Fast projectile
3959 * 0x00-0x30: If 0x02, slants toward (type>>3)-1
3960 */
3961
3962
1/2
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
189 if (wpn < 1) return;
3963
1/10
✗ Branch 0 not taken.
✓ Branch 1 taken 189 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
189 if(wpn<wEnemyWeapons && dmisc1!=9 && dmisc1!=10 && (wpn < wScript1 && wpn > wScript10) ) // Summoning doesn't require weapons
3964 return;
3965
3966
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 189 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
189 if(wpn==ewFireTrail && dmisc1>=e1t3SHOTS && dmisc1<=e1t8SHOTS)
3967 dmisc1 = e1tEACHTILE;
3968
3969 189 int32_t xoff = 0;
3970 189 int32_t yoff = 0;
3971
1/2
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
189 if ( SIZEflags&guyflagOVERRIDE_HIT_WIDTH )
3972 {
3973 xoff += (hxsz/2)-8;
3974 //Z_scripterrlog("width flag enabled. xoff = %d\n", xoff);
3975 }
3976
1/2
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
189 if ( SIZEflags&guyflagOVERRIDE_HIT_HEIGHT )
3977 {
3978 yoff += (hysz/2)-8;
3979 //Z_scripterrlog("width flag enabled. yoff = %d\n", yoff);
3980 }
3981
3982
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 189 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
189 switch(dmisc1)
3983 {
3984 case e1t5SHOTS: //BS-Aquamentus
3985 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^left)+5)<<3),wdp,dir,-1, getUID(),false));
3986 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3987 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^right)+5)<<3),wdp,dir,-1, getUID(),false));
3988 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3989
3990 [[fallthrough]];
3991 case e1t3SHOTSFAST:
3992 case e1t3SHOTS: //Aquamentus
3993 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^left)+1)<<3)+(dmisc1==e1t3SHOTSFAST ? 4:0),wdp,dir,-1, getUID(),false));
3994 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3995 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^right)+1)<<3)+(dmisc1==e1t3SHOTSFAST ? 4:0),wdp,dir,-1, getUID(),false));
3996 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
3997
3998 [[fallthrough]];
3999 default:
4000
11/20
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 189 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 189 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 189 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 189 times.
✓ Branch 12 taken 189 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 186 times.
✓ Branch 16 taken 189 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 189 times.
✗ Branch 19 not taken.
189 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(dmisc1==e1t3SHOTSFAST || dmisc1==e1tFAST ? 4:0),wdp,wpn==ewFireball2 || wpn==ewFireball ? 0:dir,-1, getUID(),false));
4001 189 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4002 189 sfx(wpnsfx(wpn),pan(int32_t(x)));
4003 189 break;
4004
4005 case e1tSLANT:
4006 {
4007 int32_t slant = 0;
4008
4009 if(((Hero.x-x) < -8 && dir==up) || ((Hero.x-x) > 8 && dir==down) || ((Hero.y-y) < -8 && dir==left) || ((Hero.y-y) > 8 && dir==right))
4010 slant = left;
4011 else if(((Hero.x-x) > 8 && dir==up) || ((Hero.x-x) < -8 && dir==down) || ((Hero.y-y) > 8 && dir==left) || ((Hero.y-y) < -8 && dir==right))
4012 slant = right;
4013
4014 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,2+(((dir^slant)+1)<<3),wdp,wpn==ewFireball2 || wpn==ewFireball ? 0:dir,-1, getUID(),false));
4015 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4016 sfx(wpnsfx(wpn),pan(int32_t(x)));
4017 break;
4018 }
4019
4020 case e1t8SHOTS: //Fire Wizzrobe
4021 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,l_up,-1, getUID(),false));
4022 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4023 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4024 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,l_down,-1, getUID(),false));
4025 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4026 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4027 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,r_up,-1, getUID(),false));
4028 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4029 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4030 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,r_down,-1, getUID(),false));
4031 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4032 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4033
4034 [[fallthrough]];
4035 case e1t4SHOTS: //Stalfos 3
4036 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,up,-1, getUID(),false));
4037 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4038 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4039 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,down,-1, getUID(),false));
4040 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4041 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4042 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,left,-1, getUID(),false));
4043 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4044 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4045 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,0,wdp,right,-1, getUID(),false));
4046 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
4047 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
4048 sfx(wpnsfx(wpn),pan(int32_t(x)));
4049 break;
4050
4051 case e1tSUMMON: // Bat Wizzrobe
4052 {
4053 //al_trace("Summon Bats\n");
4054 //zprint2("Summon Bats\n");
4055 if(dmisc4==0) break; // Summon 0
4056
4057 int32_t bc=0;
4058
4059 for(int32_t gc=0; gc<guys.Count(); gc++)
4060 {
4061 if((((enemy*)guys.spr(gc))->id) == dmisc3)
4062 {
4063 ++bc;
4064 }
4065 }
4066
4067 if(bc<=40) // Not too many enemies
4068 {
4069 int32_t kids = guys.Count();
4070 int32_t bats=(zc_oldrand()%zc_max(1,dmisc4))+1;
4071
4072 for(int32_t i=0; i<bats; i++)
4073 {
4074 //zprint2("summon\n");
4075 //al_trace("summon\n");
4076 if(addchild(x,y,dmisc3,-10, this->script_UID))
4077 {
4078 ((enemy*)guys.spr(kids+i))->count_enemy = false;
4079 //((enemy*)guys.spr(guys.Count()-1))->parent_script_UID = this->script_UID;
4080 //zprint2("Summoner Script UID: %d\n",this->script_UID);
4081
4082 }
4083 }
4084
4085 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
4086 }
4087
4088 break;
4089 }
4090
4091 case e1tSUMMONLAYER: // Summoner
4092 {
4093 if(count_layer_enemies()==0)
4094 {
4095 break;
4096 }
4097
4098 int32_t kids = guys.Count();
4099
4100 if(kids<40)
4101 {
4102 int32_t newguys=(zc_oldrand()%3)+1;
4103 bool summoned=false;
4104
4105 for(int32_t i=0; i<newguys; i++)
4106 {
4107 int32_t id2=vbound(random_layer_enemy(),eSTART,eMAXGUYS-1);
4108 int32_t x2=0;
4109 int32_t y2=0;
4110
4111 for(int32_t k=0; k<20; ++k)
4112 {
4113 x2=16*((zc_oldrand()%12)+2);
4114 y2=16*((zc_oldrand()%7)+2);
4115
4116 if((!m_walkflag(x2,y2,0,dir))&&((abs(x2-Hero.getX())>=32)||(abs(y2-Hero.getY())>=32)))
4117 {
4118 //zprint2("summon\n");
4119 //al_trace("summon\n");
4120 if(addchild(x2,y2,get_bit(quest_rules,qr_ENEMIESZAXIS) ? 64 : 0,id2,-10, this->script_UID))
4121 {
4122 ((enemy*)guys.spr(kids+i))->count_enemy = false;
4123 //((enemy*)guys.spr(guys.Count()-1))->parent_script_UID = this->script_UID;
4124 if (get_bit(quest_rules,qr_ENEMIESZAXIS) && (((enemy*)guys.spr(kids+i))->moveflags & FLAG_USE_FAKE_Z))
4125 {
4126 ((enemy*)guys.spr(kids+i))->fakez = 64;
4127 ((enemy*)guys.spr(kids+i))->z = 0;
4128 }
4129 }
4130
4131 summoned=true;
4132 break;
4133 }
4134 }
4135 }
4136
4137 if(summoned)
4138 {
4139 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
4140 }
4141 }
4142
4143 break;
4144 }
4145 }
4146 189 }
4147
4148
4149 // Hit the shield(s)?
4150 // Apparently, this function is only used for hookshots...
4151 bool enemy::hitshield(int32_t wpnx, int32_t wpny, int32_t xdir)
4152 {
4153 if(!(family==eeWALK || family==eeFIRE || family==eeOTHER))
4154 return false;
4155
4156 bool ret = false;
4157
4158 // TODO: There must be some bitwise operations that can simplify this...
4159 if(wpny > y) ret = ((flags&inv_front && xdir==down) || (flags&inv_back && xdir==up) || (flags&inv_left && xdir==left) || (flags&inv_right && xdir==right));
4160 else if(wpny < y) ret = ((flags&inv_front && xdir==up) || (flags&inv_back && xdir==down) || (flags&inv_left && xdir==right) || (flags&inv_right && xdir==left));
4161
4162 if(wpnx < x) ret = ret || ((flags&inv_front && xdir==left) || (flags&inv_back && xdir==right) || (flags&inv_left && xdir==up) || (flags&inv_right && xdir==down));
4163 else if(wpnx > x) ret = ret || ((flags&inv_front && xdir==right) || (flags&inv_back && xdir==left) || (flags&inv_left && xdir==down) || (flags&inv_right && xdir==up));
4164
4165 return ret;
4166 }
4167
4168
4169 //! Weapon Editor for 2.6
4170 //To hell with this. I'm writing new functions to resolve weapon type and defence. -Z
4171
4172
4173 //converts a wqeapon ID to its defence index.
4174 607 int32_t weaponToDefence(int32_t wid)
4175 {
4176
3/44
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 175 times.
✓ Branch 3 taken 151 times.
✓ Branch 4 taken 281 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
607 switch(wid)
4177 {
4178 case wNone: return -1;
4179 175 case wSword: return edefSWORD;
4180 151 case wBeam: return edefBEAM;
4181 281 case wBrang: return edefBRANG;
4182 case wBomb: return edefBOMB;
4183 case wSBomb: return edefSBOMB;
4184 case wLitBomb: return edefBOMB;
4185 case wLitSBomb: return edefSBOMB;
4186 case wArrow: return edefARROW;
4187 case wFire: return edefFIRE;
4188 case wWhistle:
4189 {
4190 //al_trace("Weapon resolved as a whistle, using edef: %s\n", "edefWhistle");
4191 return edefWhistle;
4192 }
4193 case wBait: return edefBAIT;
4194 case wWand: return edefWAND;
4195 case wMagic: return edefMAGIC;
4196 case wCatching: return -1;
4197 case wWind: return edefWIND;
4198 case wRefMagic: return edefREFMAGIC;
4199 case wRefFireball: return edefREFBALL;
4200 case wRefRock: return edefREFROCK;
4201 case wHammer: return edefHAMMER;
4202 case wHookshot: return edefHOOKSHOT;
4203 case wHSHandle: return edefHOOKSHOT;
4204 case wHSChain: return edefHOOKSHOT;
4205 case wSSparkle: return edefSPARKLE;
4206 case wFSparkle: return edefSPARKLE;
4207 case wSmack: return -1; // is this the candle object?
4208 case wPhantom: return -1; //engine created visual effects.
4209 case wCByrna: return edefBYRNA;
4210 case wRefBeam: return edefREFBEAM;
4211 case wStomp: return edefSTOMP;
4212 case wScript1: return edefSCRIPT01;
4213 case wScript2: return edefSCRIPT02;
4214 case wScript3: return edefSCRIPT03;
4215 case wScript4: return edefSCRIPT04;
4216 case wScript5: return edefSCRIPT05;
4217 case wScript6: return edefSCRIPT06;
4218 case wScript7: return edefSCRIPT07;
4219 case wScript8: return edefSCRIPT08;
4220 case wScript9: return edefSCRIPT09;
4221 case wScript10: return edefSCRIPT10;
4222 case wIce: return edefICE;
4223 case wSound: return edefSONIC;
4224 case wThrown: return edefTHROWN;
4225 //case wPot: return edefPOT;
4226 // case wLitZap: return edefELECTRIC;
4227 // case wZ3Sword: return edefZ3SWORD;
4228 // case wLASWord: return edefLASWORD;
4229 // case wSpinAttk: return edefSPINATTK;
4230 // case wShield: return edefSHIELD;
4231 // case wTrowel: return edefTROWEL;
4232
4233 default: return -1;
4234 }
4235 607 }
4236
4237 607 int32_t getDefType(weapon *w)
4238 {
4239 607 int32_t id = getWeaponID(w);
4240 607 int32_t edef = weaponToDefence(id);
4241
1/2
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
607 if(edef == edefHOOKSHOT)
4242 {
4243 if(w->family_class == itype_switchhook)
4244 return edefSwitchHook;
4245 }
4246 607 return edef;
4247 607 }
4248
4249 933 int32_t getWeaponID(weapon *w)
4250 {
4251 933 int32_t usewpn = w->useweapon;
4252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 933 times.
933 return (usewpn > 0) ? usewpn : w->id;
4253 }
4254
4255 607 int32_t enemy::resolveEnemyDefence(weapon *w)
4256 {
4257 //sword edef is 9, but we're reading it at 0
4258 //,
4259 607 int32_t weapondef = 0;
4260 607 int32_t wdeftype = getDefType(w);
4261 607 int32_t usedef = w->usedefence;
4262
4263
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
607 if ( usedef > 0 && (wdeftype < 0 || wdeftype >= edefLAST255 || defense[wdeftype] == 0))
4264 {
4265 weapondef = usedef*-1;
4266 }
4267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 else if(unsigned(wdeftype) < edefLAST255)
4268 {
4269 607 weapondef = wdeftype;
4270 607 }
4271 607 return weapondef;
4272 }
4273
4274 627 byte get_def_ignrflag(int32_t edef)
4275 {
4276
1/3
✓ Branch 0 taken 627 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
627 switch(edef)
4277 {
4278 case edIGNORE:
4279 case edIGNOREL1:
4280 case edSTUNORIGNORE:
4281 return WPNUNB_IGNR;
4282 case edSTUNORCHINK:
4283 case edCHINK:
4284 case edCHINKL1:
4285 case edCHINKL2:
4286 case edCHINKL4:
4287 case edCHINKL6:
4288 case edCHINKL8:
4289 case edCHINKL10:
4290 case edLEVELCHINK2:
4291 case edLEVELCHINK3:
4292 case edLEVELCHINK4:
4293 case edLEVELCHINK5:
4294 return WPNUNB_BLOCK;
4295 }
4296 627 return 0;
4297 627 }
4298
4299 627 int32_t conv_edef_unblockable(int32_t edef, byte unblockable)
4300 {
4301
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if(!(unblockable&get_def_ignrflag(edef))) return edef;
4302 switch(edef)
4303 {
4304 case edIGNORE:
4305 case edIGNOREL1:
4306 case edCHINK:
4307 case edCHINKL1:
4308 case edCHINKL2:
4309 case edCHINKL4:
4310 case edCHINKL6:
4311 case edCHINKL8:
4312 case edCHINKL10:
4313 case edLEVELCHINK2:
4314 case edLEVELCHINK3:
4315 case edLEVELCHINK4:
4316 case edLEVELCHINK5:
4317 return edNORMAL;
4318 case edSTUNORIGNORE:
4319 case edSTUNORCHINK:
4320 return edSTUNONLY;
4321 }
4322 return edef;
4323 627 }
4324
4325 // Do we do damage?
4326 // 0: takehit returns 0
4327 // 1: takehit returns 1
4328 // -1: do damage
4329 //The input from resolveEnemyDefence() for the param 'edef' is negative if a specific defence RESULT is being used.
4330 607 int32_t enemy::defendNew(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable) //May need *wpn to set return on brangs and hookshots
4331 {
4332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(switch_hooked) return 0;
4333 607 int32_t tempx = x;
4334 607 int32_t tempy = y;
4335 607 int32_t the_defence = 0;
4336
1/2
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
607 if ( edef < 0 ) //we are using a specific base default defence for a weapon
4337 {
4338 the_defence = edef*-1; //A specific defence type.
4339 }
4340 607 else the_defence = defense[edef];
4341
4342 607 the_defence = conv_edef_unblockable(the_defence, unblockable);
4343
4344
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
607 if(shieldCanBlock && !(unblockable&WPNUNB_SHLD))
4345 {
4346 switch(the_defence)
4347 {
4348 case edIGNORE:
4349 return 0;
4350 case edIGNOREL1:
4351 case edSTUNORIGNORE:
4352 if(*power <= 0)
4353 return 0;
4354 }
4355 sfx(WAV_CHINK,pan(int32_t(x)));
4356 return 1;
4357 }
4358
4359 607 int32_t new_id = id;
4360 607 int32_t effect_type = dmisc15;
4361 607 int32_t delay_timer = 90;
4362 607 enemy *gleeok = NULL;
4363 607 enemy *ptra = NULL;
4364 607 int32_t c = 0;
4365
4366
1/29
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 607 times.
607 switch(the_defence)
4367 {
4368 case edREPLACE:
4369 {
4370 sclk = 0;
4371 if ( dmisc16 > 0 ) new_id = dmisc16;
4372 else new_id = id+1;
4373 if ( new_id > 511 ) new_id = id; //Sanity bound to legal enemy IDs.
4374 if ( dmisc17 > 0 ) delay_timer = dmisc17;
4375 //if ( dmisc18 > 0 ) dummy_wpn_id = dmisc18;
4376
4377 //Z_scripterrlog("new id is %d\n", new_id);
4378 switch(guysbuf[new_id&0xFFF].family)
4379 {
4380 //Fixme: possible enemy memory leak. (minor)
4381 case eeWALK:
4382 {
4383 enemy *e = new eStalfos(x,y,new_id,clk);
4384 guys.add(e);
4385 }
4386 break;
4387
4388 case eeLEV:
4389 {
4390 enemy *e = new eLeever(x,y,new_id,clk);
4391 guys.add(e);
4392 }
4393 break;
4394
4395 case eeTEK:
4396 {
4397 enemy *e = new eTektite(x,y,new_id,clk);
4398 guys.add(e);
4399 }
4400 break;
4401
4402 case eePEAHAT:
4403 {
4404 enemy *e = new ePeahat(x,y,new_id,clk);
4405 guys.add(e);
4406 }
4407 break;
4408
4409 case eeZORA:
4410 {
4411 enemy *e = new eZora(x,y,new_id,clk);
4412 guys.add(e);
4413 }
4414 break;
4415
4416 case eeGHINI:
4417 {
4418 enemy *e = new eGhini(x,y,new_id,clk);
4419 guys.add(e);
4420 }
4421 break;
4422
4423 case eeKEESE:
4424 {
4425 enemy *e = new eKeese(x,y,new_id,clk);
4426 guys.add(e);
4427 }
4428 break;
4429
4430 case eeWIZZ:
4431 {
4432 enemy *e = new eWizzrobe(x,y,new_id,clk);
4433 guys.add(e);
4434 }
4435 break;
4436
4437 case eePROJECTILE:
4438 {
4439 enemy *e = new eProjectile(x,y,new_id,clk);
4440 guys.add(e);
4441 }
4442 break;
4443
4444 case eeWALLM:
4445 {
4446 enemy *e = new eWallM(x,y,new_id,clk);
4447 guys.add(e);
4448 }
4449 break;
4450
4451 case eeAQUA:
4452 {
4453 enemy *e = new eAquamentus(x,y,new_id,clk);
4454 guys.add(e);
4455 e->x = x;
4456 e->y = y;
4457 }
4458 break;
4459
4460 case eeMOLD:
4461 {
4462 enemy *e = new eMoldorm(x,y,new_id,zc_max(1,zc_min(254,guysbuf[new_id&0xFFF].misc1)));
4463 guys.add(e);
4464 e->x = x;
4465 e->y = y;
4466 }
4467 break;
4468
4469 case eeMANHAN:
4470 {
4471 enemy *e = new eManhandla(x,y,new_id,clk);
4472 guys.add(e);
4473 e->x = x;
4474 e->y = y;
4475 }
4476 break;
4477
4478 case eeGLEEOK:
4479 {
4480 *power = 0;
4481 gleeok = new eGleeok(x,y,new_id,guysbuf[new_id&0xFFF].misc1);
4482 guys.add(gleeok);
4483 ((enemy*)guys.spr(guys.Count()-1))->hclk = delay_timer;
4484 //((enemy*)guys.spr(guys.Count()-1))->stunclk = delay_timer;
4485 new_id &= 0xFFF;
4486 int32_t head_cnt = zc_max(1,zc_min(254,guysbuf[new_id&0xFFF].misc1));
4487 Z_scripterrlog("Gleeok head count is %d\n",head_cnt);
4488 for(int32_t i=0; i<head_cnt; i++)
4489 {
4490 //enemy *e = new esGleeok(x,y,new_id+0x1000,clk,gleeok);
4491 if(!guys.add(new esGleeok((zfix)x,(zfix)y,new_id+0x1000,c, gleeok)))
4492 {
4493 al_trace("Gleeok head %d could not be created!\n",i+1);
4494
4495 for(int32_t j=0; j<i+1; j++)
4496 {
4497 guys.del(guys.Count()-1);
4498 }
4499
4500 break;
4501 }
4502 else
4503 {
4504 ((enemy*)guys.spr(guys.Count()-1))->hclk = delay_timer;
4505 //((enemy*)guys.spr(guys.Count()-1))->stunclk = delay_timer;
4506 }
4507
4508 c-=guysbuf[new_id].misc4;
4509 //gleeok->x = x;
4510 //gleeok->y = y;
4511 //gleeok = e;
4512 }
4513 return 1;
4514 }
4515
4516 case eeGHOMA:
4517 {
4518 enemy *e = new eGohma(x,y,new_id,clk);
4519 guys.add(e);
4520 e->x = x;
4521 e->y = y;
4522 }
4523 break;
4524
4525 case eeLANM:
4526 {
4527 enemy *e = new eLanmola(x,y,new_id,zc_max(1,zc_min(253,guysbuf[new_id&0xFFF].misc1)));
4528 guys.add(e);
4529 e->x = x;
4530 e->y = y;
4531 }
4532 break;
4533
4534 case eeGANON:
4535 {
4536 enemy *e = new eGanon(x,y,new_id,clk);
4537 guys.add(e);
4538 e->x = x;
4539 e->y = y;
4540 }
4541 break;
4542
4543 case eeFAIRY:
4544 {
4545 enemy *e = new eItemFairy(x,y,new_id+0x1000*clk,clk);
4546 guys.add(e);
4547 e->x = x;
4548 e->y = y;
4549 }
4550 break;
4551
4552 case eeFIRE:
4553 {
4554 enemy *e = new eFire(x,y,new_id,clk);
4555 guys.add(e);
4556 e->x = x;
4557 e->y = y;
4558 }
4559 break;
4560
4561 case eeOTHER:
4562 {
4563 enemy *e = new eOther(x,y,new_id,clk);
4564 guys.add(e);
4565 e->x = x;
4566 e->y = y;
4567 }
4568 break;
4569
4570 case eeSPINTILE:
4571 {
4572 enemy *e = new eSpinTile(x,y,new_id,clk);
4573 guys.add(e);
4574 e->x = x;
4575 e->y = y;
4576 }
4577 break;
4578
4579 // and these enemies use the misc10/misc2 value
4580 case eeROCK:
4581 {
4582 switch(guysbuf[new_id&0xFFF].misc10)
4583 {
4584 case 1:
4585 {
4586 enemy *e = new eBoulder(x,y,new_id,clk);
4587 guys.add(e);
4588 e->x = x;
4589 e->y = y;
4590 }
4591 break;
4592
4593 case 0:
4594 default:
4595 {
4596 enemy *e = new eRock(x,y,new_id,clk);
4597 guys.add(e);
4598 e->x = x;
4599 e->y = y;
4600 }
4601 break;
4602 }
4603
4604 break;
4605 }
4606
4607 case eeTRAP:
4608 {
4609 switch(guysbuf[new_id&0xFFF].misc2)
4610 {
4611 case 1:
4612 {
4613 enemy *e = new eTrap2(x,y,new_id,clk);
4614 guys.add(e);
4615 e->x = x;
4616 e->y = y;
4617 }
4618 break;
4619
4620 case 0:
4621 default:
4622 {
4623 enemy *e = new eTrap(x,y,new_id,clk);
4624 guys.add(e);
4625 e->x = x;
4626 e->y = y;
4627 }
4628 break;
4629 }
4630
4631 break;
4632 }
4633
4634 case eeDONGO:
4635 {
4636 switch(guysbuf[new_id&0xFFF].misc10)
4637 {
4638 case 1:
4639 {
4640 enemy *e = new eDodongo2(x,y,new_id,clk);
4641 guys.add(e);
4642 e->x = x;
4643 e->y = y;
4644 }
4645 break;
4646
4647 case 0:
4648 default:
4649 {
4650 enemy *e = new eDodongo(x,y,new_id,clk);
4651 guys.add(e);
4652 e->x = x;
4653 e->y = y;
4654 }
4655 break;
4656 }
4657
4658 break;
4659 }
4660
4661 case eeDIG:
4662 {
4663 switch(guysbuf[new_id&0xFFF].misc10)
4664 {
4665 case 1:
4666 {
4667 enemy *e = new eLilDig(x,y,new_id,clk);
4668 guys.add(e);
4669 e->x = x;
4670 e->y = y;
4671 }
4672 break;
4673
4674 case 0:
4675 default:
4676 {
4677 enemy *e = new eBigDig(x,y,new_id,clk);
4678 guys.add(e);
4679 e->x = x;
4680 e->y = y;
4681 }
4682 break;
4683 }
4684
4685 break;
4686 }
4687
4688 case eePATRA:
4689 {
4690 switch(guysbuf[new_id&0xFFF].misc10)
4691 {
4692 case 1:
4693 {
4694 if (get_bit(quest_rules,qr_HARDCODED_BS_PATRA))
4695 {
4696 enemy *e = new ePatraBS(x,y,new_id,clk);
4697 guys.add(e);
4698 e->x = x;
4699 e->y = y;
4700 break;
4701 }
4702 }
4703 [[fallthrough]];
4704 case 0:
4705 default:
4706 {
4707 enemy *e = new ePatra(x,y,new_id,clk);
4708 guys.add(e);
4709 e->x = x;
4710 e->y = y;
4711 }
4712 break;
4713 }
4714
4715 break;
4716 }
4717
4718 case eeGUY:
4719 {
4720 switch(guysbuf[new_id&0xFFF].misc10)
4721 {
4722 case 1:
4723 {
4724 enemy *e = new eTrigger(x,y,new_id,clk);
4725 guys.add(e);
4726 }
4727 break;
4728
4729 case 0:
4730 default:
4731 {
4732 enemy *e = new eNPC(x,y,new_id,clk);
4733 guys.add(e);
4734 }
4735 break;
4736 }
4737
4738 break;
4739 }
4740
4741 case eeSCRIPT01:
4742 case eeSCRIPT02:
4743 case eeSCRIPT03:
4744 case eeSCRIPT04:
4745 case eeSCRIPT05:
4746 case eeSCRIPT06:
4747 case eeSCRIPT07:
4748 case eeSCRIPT08:
4749 case eeSCRIPT09:
4750 case eeSCRIPT10:
4751 case eeSCRIPT11:
4752 case eeSCRIPT12:
4753 case eeSCRIPT13:
4754 case eeSCRIPT14:
4755 case eeSCRIPT15:
4756 case eeSCRIPT16:
4757 case eeSCRIPT17:
4758 case eeSCRIPT18:
4759 case eeSCRIPT19:
4760 case eeSCRIPT20:
4761 {
4762 enemy *e = new eScript(x,y,new_id,clk);
4763 guys.add(e);
4764 e->x = x;
4765 e->y = y;
4766 break;
4767 }
4768
4769
4770 case eeFFRIENDLY01:
4771 case eeFFRIENDLY02:
4772 case eeFFRIENDLY03:
4773 case eeFFRIENDLY04:
4774 case eeFFRIENDLY05:
4775 case eeFFRIENDLY06:
4776 case eeFFRIENDLY07:
4777 case eeFFRIENDLY08:
4778 case eeFFRIENDLY09:
4779 case eeFFRIENDLY10:
4780 {
4781 enemy *e = new eFriendly(x,y,new_id,clk);
4782 guys.add(e);
4783 e->x = x;
4784 e->y = y;
4785 break;
4786 }
4787
4788
4789 default: break;
4790 }
4791
4792 // add segments of segmented enemies
4793 int32_t c=0;
4794
4795 switch(guysbuf[new_id&0xFFF].family)
4796 {
4797 case eeMOLD:
4798 {
4799 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
4800 new_id &= 0xFFF;
4801
4802 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[new_id].misc1)); i++)
4803 {
4804 //christ this is messy -DD
4805 int32_t segclk = -i*((int32_t)(8.0/(zslongToFix(guysbuf[new_id&0xFFF].step*100))));
4806
4807 if(!guys.add(new esMoldorm((zfix)x,(zfix)y,new_id+0x1000,segclk)))
4808 {
4809 al_trace("Moldorm segment %d could not be created!\n",i+1);
4810
4811 for(int32_t j=0; j<i+1; j++)
4812 guys.del(guys.Count()-1);
4813
4814 return 0;
4815 }
4816
4817 if(i>0)
4818 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
4819
4820
4821 }
4822
4823 break;
4824 }
4825
4826 case eeLANM:
4827 {
4828 new_id &= 0xFFF;
4829 int32_t shft = guysbuf[new_id].misc2;
4830 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
4831 enemy *e = new esLanmola((zfix)x,(zfix)y,new_id+0x1000,0);
4832
4833 if(!guys.add(e))
4834 {
4835 al_trace("Lanmola segment 1 could not be created!\n");
4836 guys.del(guys.Count()-1);
4837 return 0;
4838 }
4839 e->x = x;
4840 e->y = y;
4841
4842
4843
4844 for(int32_t i=1; i<zc_max(1,zc_min(253,guysbuf[new_id&0xFFF].misc1)); i++)
4845 {
4846 enemy *e2 = new esLanmola((zfix)x,(zfix)y,new_id+0x2000,-(i<<shft));
4847 if(!guys.add(e2))
4848 {
4849 al_trace("Lanmola segment %d could not be created!\n",i+1);
4850
4851 for(int32_t j=0; j<i+1; j++)
4852 guys.del(guys.Count()-1);
4853
4854 return 0;
4855 }
4856 e2->x = x;
4857 e2->y = y;
4858
4859 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
4860
4861 }
4862 }
4863 break;
4864
4865 case eeMANHAN:
4866 new_id &= 0xFFF;
4867
4868 for(int32_t i=0; i<((!(guysbuf[new_id].misc2))?4:8); i++)
4869 {
4870 if(!guys.add(new esManhandla((zfix)x,(zfix)y,new_id+0x1000,i)))
4871 {
4872 al_trace("Manhandla head %d could not be created!\n",i+1);
4873
4874 for(int32_t j=0; j<i+1; j++)
4875 {
4876 guys.del(guys.Count()-1);
4877 }
4878
4879 return 0;
4880 }
4881
4882
4883 ((enemy*)guys.spr(guys.Count()-1))->frate=guysbuf[new_id].misc1;
4884 }
4885
4886 break;
4887
4888 case eeGLEEOK:
4889 {
4890 /*
4891 new_id &= 0xFFF;
4892 int32_t head_cnt = zc_max(1,zc_min(254,guysbuf[new_id&0xFFF].misc1));
4893 Z_scripterrlog("Gleeok head count is %d\n",head_cnt);
4894 for(int32_t i=0; i<head_cnt; i++)
4895 {
4896 //enemy *e = new esGleeok(x,y,new_id+0x1000,clk,gleeok);
4897 if(!guys.add(new esGleeok((zfix)x,(zfix)y,new_id+0x1000,c, gleeok)))
4898 {
4899 al_trace("Gleeok head %d could not be created!\n",i+1);
4900
4901 for(int32_t j=0; j<i+1; j++)
4902 {
4903 guys.del(guys.Count()-1);
4904 }
4905
4906 break;
4907 }
4908
4909 c-=guysbuf[new_id].misc4;
4910 */
4911
4912 // }
4913 }
4914 break;
4915
4916
4917 case eePATRA:
4918 {
4919 new_id &= 0xFFF;
4920 int32_t outeyes = 0;
4921 ptra = new ePatraBS((zfix)x,(zfix)y,id,clk);
4922
4923 for(int32_t i=0; i<zc_min(254,guysbuf[new_id&0xFFF].misc1); i++)
4924 {
4925 if(!((guysbuf[new_id].misc10&&get_bit(quest_rules,qr_HARDCODED_BS_PATRA))?guys.add(new esPatraBS((zfix)x,(zfix)y,new_id+0x1000,i,ptra)):guys.add(new esPatra((zfix)x,(zfix)y,new_id+0x1000,i,ptra))))
4926 {
4927 al_trace("Patra outer eye %d could not be created!\n",i+1);
4928
4929 for(int32_t j=0; j<i+1; j++)
4930 guys.del(guys.Count()-1);
4931
4932 return 0;
4933 }
4934 else
4935 outeyes++;
4936
4937
4938 }
4939
4940 for(int32_t i=0; i<zc_min(254,guysbuf[new_id&0xFFF].misc2); i++)
4941 {
4942 if(!guys.add(new esPatra((zfix)x,(zfix)y,new_id+0x1000,i,ptra)))
4943 {
4944 al_trace("Patra inner eye %d could not be created!\n",i+1);
4945
4946 for(int32_t j=0; j<i+1+zc_min(254,outeyes); j++)
4947 guys.del(guys.Count()-1);
4948
4949 return 0;
4950 }
4951
4952
4953 }
4954 delete ptra;
4955 break;
4956 }
4957 }
4958
4959
4960
4961 ((enemy*)guys.spr(guys.Count()-1))->count_enemy = true;
4962 ((enemy*)guys.spr(guys.Count()-1))->stunclk = delay_timer;
4963 ((enemy*)guys.spr(guys.Count()-1))->dir = this->dir;
4964 ((enemy*)guys.spr(guys.Count()-1))->scale = this->scale;
4965 ((enemy*)guys.spr(guys.Count()-1))->angular = this->angular;
4966 ((enemy*)guys.spr(guys.Count()-1))->angle = this->angle;
4967 ((enemy*)guys.spr(guys.Count()-1))->rotation = this->rotation;
4968 //((enemy*)guys.spr(guys.Count()-1))->mainguy = this->mainguy; //This might mean that it is a core.
4969 ((enemy*)guys.spr(guys.Count()-1))->itemguy = this->itemguy;
4970 ((enemy*)guys.spr(guys.Count()-1))->leader = this->leader;
4971 ((enemy*)guys.spr(guys.Count()-1))->hclk = delay_timer;
4972 ((enemy*)guys.spr(guys.Count()-1))->script_spawned = this->script_spawned;
4973 ((enemy*)guys.spr(guys.Count()-1))->script_UID = this->script_UID;
4974 ((enemy*)guys.spr(guys.Count()-1))->sclk = 0;
4975
4976
4977 item_set = 0; //Do not make a drop.
4978
4979 switch(effect_type)
4980 {
4981 case -7:
4982 {
4983 weapon *w = new weapon(x,y-fakez,z,wBomb,0,wdp,0,-1,getUID(),false, 0);
4984 Lwpns.add(w);
4985 break;
4986 }
4987 case -6:
4988 {
4989 weapon *w = new weapon(x,y-fakez,z,wSBomb,0,wdp,0,-1,getUID(),false, 0);
4990 Lwpns.add(w);
4991 break;
4992 }
4993 case -5:
4994 {
4995 weapon *w = new weapon(x,y-fakez,z,wBomb,effect_type,0,0,Hero.getUID(), txsz, tysz);
4996 Lwpns.add(w);
4997 break;
4998 }
4999 case -4:
5000 {
5001 weapon *w = new weapon(x,y-fakez,z,wSBomb,effect_type,0,0,Hero.getUID(), txsz, tysz);
5002 Lwpns.add(w);
5003 break;
5004 }
5005 case -3: explode(1); break;
5006 case -2: explode(2); break;
5007 case -1: explode(0); break;
5008 case 0: break;
5009
5010 default:
5011 {
5012 //Dummy weapon function
5013 if ( effect_type > 255 ) effect_type = 0; //Sanity bound the sprite ID.
5014 weapon *w = new weapon(x,y-fakez,z,wSSparkle,effect_type,0,0,Hero.getUID(), txsz, tysz,0,0,0,0,0,0,0);
5015 Lwpns.add(w);
5016 break;
5017 }
5018 }
5019
5020
5021 yofs = -32768;
5022 switch(guysbuf[new_id&0xFFF].family)
5023 {
5024 case eeGLEEOK:
5025 {
5026 Z_scripterrlog("Replacing a gleeok.\n");
5027 enemy *tempenemy = (enemy *) guys.getByUID(parentCore);
5028 hp = -999;
5029 tempenemy->hp = -999;
5030 break;
5031
5032 }
5033 default:
5034 hp = -1000; break;
5035 }
5036 ++game->guys[(currmap*MAPSCRSNORMAL)+currscr];
5037 return 1;
5038
5039 }
5040 case edSPLIT:
5041 {
5042 //int32_t ex = x; int32_t ey = y;
5043 //al_trace("edSplit dmisc3: %d\n", dmisc3);
5044 //al_trace("edSplit dmisc4: %d\n", dmisc4);
5045 /*
5046 if ( txsx > 1 )
5047 {
5048 ex += ( txsz-1 ) * 8; //from its middle
5049 }
5050 if ( tysx > 1 )
5051 {
5052 ey += ( tysz-1 ) * 8; //from its middle
5053 }
5054 */
5055 for ( int32_t q = 0; q < dmisc4; q++ )
5056 {
5057
5058 //addenemy((x+(txsz*16)/2),(y+(tysz*16)/2),dmisc3+0x1000,-15);
5059 addenemy(
5060 //ex,ey,
5061 x,y,
5062 dmisc3+0x1000,-15);
5063 //addenemy(ex,ey,dmisc3,0);
5064
5065 }
5066 item_set = 0; //Do not make a drop.
5067 hp = -1000;
5068 return -1;
5069
5070 }
5071 case edSUMMON:
5072 {
5073
5074
5075 //al_trace("edSplit dmisc3: %d\n", dmisc3);
5076 //al_trace("edSplit dmisc4: %d\n", dmisc4);
5077 int32_t summon_count = (zc_oldrand()%dmisc4)+1;
5078 for ( int32_t q = 0; q < summon_count; q++ )
5079 {
5080 int32_t x2=16*((zc_oldrand()%12)+2);
5081 int32_t y2=16*((zc_oldrand()%7)+2);
5082 addenemy(
5083 //(x+(txsz*16)/2),(y+(tysz*16)/2)
5084 x2,y2,
5085 dmisc3+0x1000,-15);
5086 //addenemy(ex,ey,dmisc3,0);
5087
5088 }
5089 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
5090 return -1;
5091
5092 }
5093
5094 case edEXPLODESMALL:
5095 {
5096 weapon *ew=new weapon(x,y-fakez,z, ewBomb, 0, dmisc4, dir,-1,getUID(),false);
5097 Ewpns.add(ew);
5098 item_set = 0; //Should we make a drop?
5099 hp = -1000;
5100 return -1;
5101 }
5102
5103
5104 case edEXPLODEHARMLESS:
5105 {
5106 weapon *ew=new weapon(x,y-fakez,z, ewSBomb, 0, dmisc4, dir,-1,getUID(),false);
5107 Ewpns.add(ew);
5108 ew->hyofs = -32768;
5109 item_set = 0; //Should we make a drop?
5110 hp = -1000;
5111 return -1;
5112 }
5113
5114
5115 case edEXPLODELARGE:
5116 {
5117 weapon *ew=new weapon(x,y-fakez,z, ewSBomb, 0, dmisc4, dir,-1,getUID(),false);
5118 Ewpns.add(ew);
5119
5120 hp = -1000;
5121 return -1;
5122 }
5123
5124
5125 case edTRIGGERSECRETS:
5126 {
5127 hidden_entrance(0, true, false, -4);
5128 return -1;
5129 }
5130
5131 case edSTUNORCHINK:
5132 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK))
5133 {
5134 sfx(WAV_CHINK,pan(int32_t(x)));
5135 return 1;
5136 }
5137 else if(*power <= 0)
5138 {
5139 //al_trace("defendNew() is at: %s\n", "returning edSTUNORCHINK");
5140 sfx(WAV_CHINK,pan(int32_t(x)));
5141 return 1;
5142 }
5143 [[fallthrough]];
5144
5145 case edSTUNORIGNORE:
5146 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK))
5147 {
5148 sfx(WAV_CHINK,pan(int32_t(x)));
5149 return 1;
5150 }
5151 else if(*power <= 0)
5152 return 0;
5153 [[fallthrough]];
5154
5155 case edSTUNONLY:
5156 if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wHookshot || wpnId==wSword) && stunclk>=159)
5157 {
5158 //al_trace("enemy::defend(), edSTUNONLY found a weapon of type FIRE, BOMB, SBOMB, HOOKSHOT, or SWORD:, with wpnId: \n", wpnId);
5159 // Z_message("enemy::defend(), edSTUNONLY found a weapon of type FIRE, BOMB, SBOMB, HOOKSHOT, or SWORD:, with wpnId: \n", wpnId);
5160 return 1;
5161 }
5162 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK))
5163 {
5164 sfx(WAV_CHINK,pan(int32_t(x)));
5165 return 1;
5166 }
5167 else
5168 {
5169 stunclk=160;
5170 sfx(WAV_EHIT,pan(int32_t(x)));
5171
5172 return 1;
5173 }
5174
5175 case edCHINKL1:
5176 if(*power >= 1*game->get_hero_dmgmult()) break;
5177 [[fallthrough]];
5178 case edCHINKL2:
5179 if(*power >= 2*game->get_hero_dmgmult()) break;
5180 [[fallthrough]];
5181 case edCHINKL4:
5182 if(*power >= 4*game->get_hero_dmgmult()) break;
5183 [[fallthrough]];
5184 case edCHINKL6:
5185 if(*power >= 6*game->get_hero_dmgmult()) break;
5186 [[fallthrough]];
5187 case edCHINKL8:
5188 if(*power >= 8*game->get_hero_dmgmult()) break;
5189 [[fallthrough]];
5190 case edCHINKL10:
5191 if(*power >= 10*game->get_hero_dmgmult()) break;
5192 [[fallthrough]];
5193 case edCHINK:
5194 //al_trace("defendNew() is at: %s\n", "returning edCHINK");
5195 sfx(WAV_CHINK,pan(int32_t(x)));
5196 return 1;
5197
5198 case edIGNOREL1:
5199 if(*power > 0) break;
5200 [[fallthrough]];
5201
5202 case edIGNORE:
5203 return 0;
5204
5205 case ed1HKO:
5206 *power = hp;
5207 return -2;
5208
5209 case ed2x:
5210 {
5211 *power = zc_max(1,*power*2);
5212 //int32_t pow = *power;
5213 //*power = vbound((pow*2),0,214747);
5214 return -1;
5215 }
5216 case ed3x:
5217 {
5218 *power = zc_max(1,*power*3);
5219 //int32_t pow = *power;
5220 //*power = vbound((pow*3),0,214747);
5221 return -1;
5222 }
5223
5224 case ed4x:
5225 {
5226 *power = zc_max(1,*power*4);
5227 //int32_t pow = *power;
5228 //*power = vbound((pow*4),0,214747);
5229 return -1;
5230 }
5231
5232
5233 case edHEAL:
5234 { //Probably needs its own function, or routine in the damage functuon to heal if power is negative.
5235 //int32_t pow = *power;
5236 //*power = vbound((pow*-1),0,214747);
5237 //break;
5238 *power = zc_min(0,*power*-1);
5239 return -1;
5240 }
5241 /*
5242 case edLEVELDAMAGE:
5243 {
5244 int32_t pow = *power;
5245 int32_t lvl = *level;
5246 *power = vbound((pow*lvl),0,214747);
5247 break;
5248 }
5249 case edLEVELREDUCTION:
5250 {
5251 int32_t pow = *power;
5252 int32_t lvl = *level;
5253 *power = vbound((pow/lvl),0,214747);
5254 break;
5255 }
5256 */
5257
5258 case edQUARTDAMAGE:
5259 *power = zc_max(1,*power/2);
5260
5261 [[fallthrough]];
5262 case edHALFDAMAGE:
5263 *power = zc_max(1,*power/2);
5264 break;
5265
5266 case edSWITCH:
5267 {
5268 if(Hero.switchhookclk) return 0; //Already switching!
5269 switch(family)
5270 {
5271 case eeAQUA: case eeMOLD: case eeDONGO: case eeMANHAN: case eeGLEEOK:
5272 case eeDIG: case eeGHOMA: case eeLANM: case eePATRA: case eeGANON:
5273 return 0;
5274 }
5275 hooked_combopos = -1;
5276 hooked_layerbits = 0;
5277 switching_object = this;
5278 switch_hooked = true;
5279 Hero.doSwitchHook(game->get_switchhookstyle());
5280 if(QMisc.miscsfx[sfxSWITCHED])
5281 sfx(QMisc.miscsfx[sfxSWITCHED],int32_t(x));
5282 return 1;
5283 }
5284
5285 case 0:
5286 {
5287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(edef == edefSwitchHook)
5288 return -1;
5289
3/6
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 348 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 259 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
607 if (stunclk && get_bit(quest_rules, qr_NO_STUNLOCK) && *power == 0)
5290 {
5291 sfx(WAV_CHINK,pan(int32_t(x)));
5292 return 1;
5293 }
5294
5295 }
5296 607 }
5297
5298 607 return -1;
5299 607 }
5300
5301 607 int32_t enemy::defendNewInt(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable, weapon* w)
5302 {
5303 607 std::vector<int32_t> &ev = FFCore.eventData;
5304 607 ev.clear();
5305 607 ev.push_back(*power*10000);
5306 607 ev.push_back(edef*10000);
5307 607 ev.push_back(unblockable*10000);
5308 607 ev.push_back(wpnId*10000);
5309 607 ev.push_back(0);
5310 607 ev.push_back(getUID());
5311
1/2
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
607 ev.push_back(w?w->getUID():0);
5312
5313 607 throwGenScriptEvent(GENSCR_EVENT_ENEMY_HIT1);
5314 607 *power = ev[0]/10000;
5315 607 edef = ev[1]/10000;
5316 607 unblockable = byte(ev[2]/10000);
5317 607 wpnId = ev[3] / 10000;
5318 607 bool nullify = ev[4]!=0;
5319 607 ev.clear();
5320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(nullify) return 0;
5321
5322 607 int32_t ret = defendNew(wpnId, power, edef, unblockable);
5323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(ret != -1) return ret;
5324 607 ev.push_back(*power*10000);
5325 607 ev.push_back(edef*10000);
5326 607 ev.push_back(unblockable*10000);
5327 607 ev.push_back(wpnId*10000);
5328 607 ev.push_back(0);
5329 607 ev.push_back(getUID());
5330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 ev.push_back(w?w->getUID():0);
5331
5332 607 throwGenScriptEvent(GENSCR_EVENT_ENEMY_HIT2);
5333 607 *power = ev[0]/10000;
5334 607 nullify = ev[4]!=0;
5335 607 ev.clear();
5336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 607 times.
607 if(nullify) return 0;
5337 607 return -1;
5338 607 }
5339
5340 326 int32_t enemy::defenditemclassNew(int32_t wpnId, int32_t *power, weapon *w)
5341 {
5342 326 int32_t wid = getWeaponID(w);
5343
5344 326 int32_t edef = resolveEnemyDefence(w);
5345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
326 if(QHeader.zelda_version > 0x250)
5346 return defendNewInt(wid, power, edef, w->unblockable, w);
5347
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
✗ Branch 2 not taken.
326 switch(wid)
5348 {
5349 case wScript1: case wScript2: case wScript3: case wScript4: case wScript5:
5350 case wScript6: case wScript7: case wScript8: case wScript9: case wScript10:
5351 return defend(wpnId, power, edefSCRIPT);
5352
5353 case wWhistle:
5354 return -1;
5355
5356 default:
5357 326 return defendNewInt(wid, power, edef, w->unblockable, w);
5358 }
5359 326 }
5360
5361
5362 // Check defenses without actually acting on them.
5363 bool enemy::candamage(int32_t power, int32_t edef, byte unblockable)
5364 {
5365 switch(defense[edef])
5366 {
5367 case edSTUNONLY:
5368 return false;
5369 case edSTUNORCHINK:
5370 case edCHINK:
5371 return unblockable&WPNUNB_BLOCK;
5372 case edSTUNORIGNORE:
5373 case edIGNORE:
5374 return unblockable&WPNUNB_IGNR;
5375
5376 case edIGNOREL1:
5377 return (unblockable&WPNUNB_IGNR) || power >= 1*game->get_hero_dmgmult();
5378 case edCHINKL1:
5379 return (unblockable&WPNUNB_BLOCK) || power >= 1*game->get_hero_dmgmult();
5380
5381 case edCHINKL2:
5382 return (unblockable&WPNUNB_BLOCK) || power >= 2*game->get_hero_dmgmult();
5383
5384 case edCHINKL4:
5385 return (unblockable&WPNUNB_BLOCK) || power >= 4*game->get_hero_dmgmult();
5386
5387 case edCHINKL6:
5388 return (unblockable&WPNUNB_BLOCK) || power >= 6*game->get_hero_dmgmult();
5389
5390 case edCHINKL8:
5391 return (unblockable&WPNUNB_BLOCK) || power >= 8*game->get_hero_dmgmult();
5392 }
5393
5394 return true;
5395 }
5396
5397 // Do we do damage?
5398 // 0: takehit returns 0
5399 // 1: takehit returns 1
5400 // -1: do damage
5401 int32_t enemy::defend(int32_t wpnId, int32_t *power, int32_t edef)
5402 {
5403 if(shieldCanBlock)
5404 {
5405 switch(defense[edef])
5406 {
5407 case edIGNORE:
5408 return 0;
5409 case edIGNOREL1:
5410 case edSTUNORIGNORE:
5411 if(*power <= 0)
5412 return 0;
5413 }
5414
5415 sfx(WAV_CHINK,pan(int32_t(x)));
5416 return 1;
5417 }
5418
5419 switch(defense[edef])
5420 {
5421 case edSTUNORCHINK:
5422 if(*power <= 0)
5423 {
5424 sfx(WAV_CHINK,pan(int32_t(x)));
5425 return 1;
5426 }
5427
5428 [[fallthrough]];
5429 case edSTUNORIGNORE:
5430 if(*power <= 0)
5431 return 0;
5432
5433 [[fallthrough]];
5434 case edSTUNONLY:
5435 if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wHookshot || wpnId==wSword) && stunclk>=159)
5436 return 1;
5437
5438 stunclk=160;
5439 sfx(WAV_EHIT,pan(int32_t(x)));
5440 return 1;
5441
5442 case edFREEZE:
5443 frozenclock=-1;
5444 //sfx(WAV_FREEZE,pan(int32_t(x)));
5445 return 1;
5446
5447 case edCHINKL1:
5448 if(*power >= 1*game->get_hero_dmgmult()) break;
5449 [[fallthrough]];
5450 case edCHINKL2:
5451 if(*power >= 2*game->get_hero_dmgmult()) break;
5452 [[fallthrough]];
5453 case edCHINKL4:
5454 if(*power >= 4*game->get_hero_dmgmult()) break;
5455 [[fallthrough]];
5456 case edCHINKL6:
5457 if(*power >= 6*game->get_hero_dmgmult()) break;
5458 [[fallthrough]];
5459 case edCHINKL8:
5460 if(*power >= 8*game->get_hero_dmgmult()) break;
5461 [[fallthrough]];
5462 case edCHINKL10:
5463 if(*power >= 10*game->get_hero_dmgmult()) break;
5464 [[fallthrough]];
5465 case edCHINK:
5466 sfx(WAV_CHINK,pan(int32_t(x)));
5467 return 1;
5468 case edTRIGGERSECRETS:
5469 hidden_entrance(0, true, false, -4);
5470 break;
5471
5472 case edIGNOREL1:
5473 if(*power > 0) break;
5474 [[fallthrough]];
5475 case edIGNORE:
5476 return 0;
5477
5478 case ed1HKO:
5479 *power = hp;
5480 return -2;
5481
5482 case ed2x:
5483 {
5484 *power = zc_max(1,*power*2);
5485 //int32_t pow = *power;
5486 //*power = vbound((pow*2),0,214747);
5487 return -1;
5488 }
5489 case ed3x:
5490 {
5491 *power = zc_max(1,*power*3);
5492 //int32_t pow = *power;
5493 //*power = vbound((pow*3),0,214747);
5494 return -1;
5495 }
5496
5497 case ed4x:
5498 {
5499 *power = zc_max(1,*power*4);
5500 //int32_t pow = *power;
5501 //*power = vbound((pow*4),0,214747);
5502 return -1;
5503 }
5504
5505
5506 case edHEAL:
5507 { //Probably needs its own function, or routine in the damage functuon to heal if power is negative.
5508 //int32_t pow = *power;
5509 //*power = vbound((pow*-1),0,214747);
5510 //break;
5511 *power = zc_min(0,*power*-1);
5512 return -1;
5513 }
5514 /*
5515 case edLEVELDAMAGE:
5516 {
5517 int32_t pow = *power;
5518 int32_t lvl = *level;
5519 *power = vbound((pow*lvl),0,214747);
5520 break;
5521 }
5522 case edLEVELREDUCTION:
5523 {
5524 int32_t pow = *power;
5525 int32_t lvl = *level;
5526 *power = vbound((pow/lvl),0,214747);
5527 break;
5528 }
5529 */
5530
5531
5532 case edQUARTDAMAGE:
5533 *power = zc_max(1,*power/2);
5534
5535 [[fallthrough]];
5536 case edHALFDAMAGE:
5537 *power = zc_max(1,*power/2);
5538 break;
5539 }
5540
5541 return -1;
5542 }
5543
5544 // Defend against a particular item class.
5545 int32_t enemy::defenditemclass(int32_t wpnId, int32_t *power)
5546 {
5547 int32_t def=-1;
5548
5549 switch(wpnId)
5550 {
5551 // These first 2 are only used by Gohma... enemy::takehit() has complicated stun-calculation code for these.
5552 case wBrang:
5553 def = defend(wpnId, power, edefBRANG);
5554 break;
5555
5556 case wHookshot:
5557 def = defend(wpnId, power, edefHOOKSHOT);
5558 break;
5559
5560 // Anyway...
5561 case wBomb:
5562 def = defend(wpnId, power, edefBOMB);
5563 break;
5564
5565 case wSBomb:
5566 def = defend(wpnId, power, edefSBOMB);
5567 break;
5568
5569 case wArrow:
5570 def = defend(wpnId, power, edefARROW);
5571 break;
5572
5573 case wFire:
5574 def = defend(wpnId, power, edefFIRE);
5575 break;
5576
5577 case wWand:
5578 def = defend(wpnId, power, edefWAND);
5579 break;
5580
5581 case wMagic:
5582 def = defend(wpnId, power, edefMAGIC);
5583 break;
5584
5585 case wHammer:
5586 def = defend(wpnId, power, edefHAMMER);
5587 break;
5588
5589 case wSword:
5590 def = defend(wpnId, power, edefSWORD);
5591 break;
5592
5593 case wBeam:
5594 def = defend(wpnId, power, edefBEAM);
5595 break;
5596
5597 case wRefBeam:
5598 def = defend(wpnId, power, edefREFBEAM);
5599 break;
5600
5601 case wRefMagic:
5602 def = defend(wpnId, power, edefREFMAGIC);
5603 break;
5604
5605 case wRefFireball:
5606 def = defend(wpnId, power, edefREFBALL);
5607 break;
5608
5609 case wRefRock:
5610 def = defend(wpnId, power, edefREFROCK);
5611 break;
5612
5613 case wStomp:
5614 def = defend(wpnId, power, edefSTOMP);
5615 break;
5616
5617 case wCByrna:
5618 def = defend(wpnId, power, edefBYRNA);
5619 break;
5620
5621 case wScript1:
5622 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT01);
5623 else def = defend(wpnId, power, edefSCRIPT);
5624 break;
5625
5626 case wScript2:
5627 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT02);
5628 else def = defend(wpnId, power, edefSCRIPT);
5629 break;
5630
5631 case wScript3:
5632 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT03);
5633 else def = defend(wpnId, power, edefSCRIPT);
5634 break;
5635
5636 case wScript4:
5637 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT04);
5638 else def = defend(wpnId, power, edefSCRIPT);
5639 break;
5640
5641 case wScript5:
5642 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT05);
5643 else def = defend(wpnId, power, edefSCRIPT);
5644 break;
5645
5646 case wScript6:
5647 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT06);
5648 else def = defend(wpnId, power, edefSCRIPT);
5649 break;
5650
5651 case wScript7:
5652 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT07);
5653 else def = defend(wpnId, power, edefSCRIPT);
5654 break;
5655
5656 case wScript8:
5657 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT08);
5658 else def = defend(wpnId, power, edefSCRIPT);
5659 break;
5660
5661 case wScript9:
5662 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT09);
5663 else def = defend(wpnId, power, edefSCRIPT);
5664 break;
5665
5666 case wScript10:
5667 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefSCRIPT10);
5668 else def = defend(wpnId, power, edefSCRIPT);
5669 break;
5670
5671 case wWhistle:
5672 if(QHeader.zelda_version > 0x250) def = defend(wpnId, power, edefWhistle);
5673 else break;
5674 break;
5675
5676
5677 //!ZoriaRPG : We need some special cases here, to ensure that old script defs don;t break.
5678 //Probably best to do this from the qest file, loading the values of Script(generic) into each
5679 //of the ten if the quest version is lower than N.
5680 //Either that, or we need a boolean flag to set int32_t he enemy editor, or by ZScript that changes this behaviour.
5681 //such as bool UseSeparatedScriptDefences. hah.
5682 default:
5683 //if(wpnId>=wScript1 && wpnId<=wScript10)
5684 // {
5685 // def = defend(wpnId, power, edefSCRIPT);
5686 // }
5687 // }
5688
5689 break;
5690 }
5691
5692 return def;
5693 }
5694
5695 // take damage or ignore it
5696 // -1: damage (if any) dealt
5697 // 1: blocked
5698 // 0: weapon passes through unhindered
5699 607 int32_t enemy::takehit(weapon *w)
5700 {
5701
2/4
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 607 times.
607 if(fallclk||drownclk) return 0;
5702 607 int32_t wpnId = w->id;
5703 //al_trace("takehit() wpnId is %d\n",wpnId);
5704 //if ( wpnId == wWhistle ) al_trace("Whistle weapon in %s\n", "takehit");
5705 607 int32_t power = w->power;
5706 607 int32_t wpnx = w->x;
5707 607 int32_t wpny = w->y;
5708 607 int32_t enemyHitWeapon = w->parentitem;
5709 int32_t wpnDir;
5710 607 int32_t parent_item = w->parentitem;
5711
5712 //if ( parent_item > -1 )
5713 //{
5714 // if ( itemsbuf[parent_item].useweapon > 0 /*&& wpnId != wWhistle*/ )
5715 // {
5716 // wpnId = itemsbuf[parent_item].useweapon;
5717 // }
5718
5719 //}
5720 //if ( parent_item == -1 && w->ScriptGenerated )
5721 //{
5722 // if ( w->useweapon > 0 /*&& wpnId != wWhistle*/ )
5723 // {
5724 // wpnId = w->useweapon;
5725 // }
5726
5727 //}
5728 //al_trace("takehit wpnId is: %d\n",wpnId);
5729
5730 //Shoud be set from idata from the weapon::weaon constructor. -Z
5731
1/2
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
607 if ( w->useweapon > 0 /*&& wpnId != wWhistle*/ )
5732 {
5733 wpnId = w->useweapon;
5734 }
5735
5736 //al_trace("takehit() useweapon is %d\n",itemsbuf[parent_item].useweapon);
5737
5738 //Weapon Editor -Z
5739
5740
5741 // If it's a boomerang that just bounced, use the opposite direction;
5742 // otherwise, it might bypass a shield. This probably won't handle
5743 // every case correctly, but it's better than having shields simply
5744 // not work against boomerangs.
5745
8/8
✓ Branch 0 taken 281 times.
✓ Branch 1 taken 326 times.
✓ Branch 2 taken 169 times.
✓ Branch 3 taken 112 times.
✓ Branch 4 taken 168 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 148 times.
607 if(w->id==wBrang && w->misc==1 && w->clk2>=256 && w->clk2<264)
5746 148 wpnDir = oppositeDir[w->dir];
5747 else
5748 459 wpnDir = w->dir;
5749
5750
4/8
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 607 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 607 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 607 times.
607 if(dying || clk<0 || hclk>0 || superman)
5751 {
5752 return 0;
5753 }
5754
5755 //Prevent boomerang from writing to hitby[] for more than one frame.
5756 //This also prevents stunlock.
5757 //if ( stunclk > 0 ) return 0;
5758 //this needs a rule for boomerangs that cannot stunlock!
5759 //further, bouncing weapons should probably SFX_CHINK and bounce here.
5760 //sigh.
5761
5762 607 int32_t ret = -1;
5763
5764 // This obscure quest rule...
5765
4/6
✓ Branch 0 taken 426 times.
✓ Branch 1 taken 181 times.
✓ Branch 2 taken 426 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 426 times.
607 if(get_bit(quest_rules,qr_BOMBDARKNUTFIX) && (wpnId==wBomb || wpnId==wSBomb))
5766 {
5767 double _MSVC2022_tmp1, _MSVC2022_tmp2;
5768 double ddir=atan2_MSVC2022_FIX(double(wpny-y),double(x-wpnx));
5769 wpnDir=zc_oldrand()&3;
5770
5771 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
5772 {
5773 wpnDir=down;
5774 }
5775 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
5776 {
5777 wpnDir=right;
5778 }
5779 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
5780 {
5781 wpnDir=up;
5782 }
5783 else
5784 {
5785 wpnDir=left;
5786 }
5787 }
5788
5789 607 int32_t xdir = dir;
5790 607 shieldCanBlock=false;
5791
5792 //if (family==eeFLOAT && flags&(inv_front|inv_back_inv_left|inv_right)) xdir=down;
5793
2/4
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 607 times.
607 if(!(w->unblockable&WPNUNB_BLOCK)&&((wpnId==wHookshot && hitshield(wpnx, wpny, xdir))
5794
7/10
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 607 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 607 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 607 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 607 times.
607 || ((flags&inv_front && wpnDir==(xdir^down)) || (flags&inv_back && wpnDir==(xdir^up)) || (flags&inv_left && wpnDir==(xdir^left)) || (flags&inv_right && wpnDir==(xdir^right))))
5795 )
5796 // The hammer should already be dealt with by subclasses (Walker etc.)
5797 {
5798
0/9
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
16 switch(wpnId)
5799 {
5800 // Weapons which shields protect against
5801 case wSword:
5802 case wWand:
5803 if(Hero.getCharging()>0)
5804 Hero.setAttackClk(Hero.getAttackClk()+1); //Cancel charging
5805
5806 [[fallthrough]];
5807 case wHookshot:
5808 case wHSHandle:
5809 case wBrang:
5810 shieldCanBlock=true;
5811 break;
5812
5813 case wBeam:
5814 case wRefBeam:
5815 // Mirror shielded enemies!
5816 #if 0
5817 if(false /*flags2&guy_mirror*/ && !get_bit(quest_rules,qr_SWORDMIRROR))
5818 {
5819 if(wpnId>wEnemyWeapons)
5820 return 0;
5821
5822 sfx(WAV_CHINK,pan(int32_t(x)));
5823 return 1;
5824 }
5825
5826 #endif
5827
5828 [[fallthrough]];
5829 case wRefRock:
5830 case wRefFireball:
5831 case wMagic:
5832 #if 0
5833 if(false /*flags2&guy_mirror*/ && (wpnId!=wRefRock || get_bit(quest_rules,qr_REFLECTROCKS)))
5834 {
5835 sfx(WAV_CHINK,pan(int32_t(x)));
5836 return 3;
5837 }
5838
5839 #endif
5840
5841 if(wpnId>wEnemyWeapons)
5842 return 0;
5843
5844 [[fallthrough]];
5845 default:
5846 shieldCanBlock=true;
5847 break;
5848
5849 // Bombs
5850 case wSBomb:
5851 case wBomb:
5852 if (!get_bit(quest_rules,qr_TRUEFIXEDBOMBSHIELD)) goto hitclock;
5853 else if (!get_bit(quest_rules,qr_BOMBSPIERCESHIELD))
5854 {
5855 sfx(WAV_CHINK,pan(int32_t(x)));
5856 return 0;
5857 }
5858 else break;
5859
5860 // Weapons which ignore shields
5861 case wWhistle:
5862 case wHammer:
5863 break;
5864
5865 // Weapons which shouldn't be removed by shields
5866 case wLitBomb:
5867 case wLitSBomb:
5868 case wWind:
5869 case wPhantom:
5870 case wSSparkle:
5871 case wBait:
5872 return 0;
5873
5874 [[fallthrough]];
5875 case wFire:
5876 #if 0
5877 if(false /*flags2&guy_mirror*/)
5878 {
5879 sfx(WAV_CHINK,pan(int32_t(x)));
5880 return 1;
5881 }
5882
5883 #endif
5884 ;
5885 }
5886 }
5887
5888
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 281 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
607 switch(wpnId)
5889 {
5890 case wWhistle: //No longer completely ignore whistle weapons! -Z
5891 {
5892
5893 if ( ((itemsbuf[parent_item].flags & ITEM_FLAG2) == 0) || ( parent_item == -1 ) ) //if the flag is set, or the weapon is scripted
5894 {
5895 //al_trace("Whistle weapon in %s\n", "takehit flag == 0");
5896 return 0; break;
5897 }
5898 else
5899 {
5900 w->power = power = itemsbuf[parent_item].misc5;
5901
5902 int32_t def = defendNewInt(wpnId, &power, resolveEnemyDefence(w), w->unblockable, w);
5903
5904 if(def <= 0)
5905 {
5906 if ( def == -2 ) hp -= hp;
5907 else hp -= power;
5908 return def;
5909 }
5910 break;
5911 }
5912 break;
5913 }
5914
5915 case wPhantom:
5916 return 0;
5917
5918 case wLitBomb:
5919 case wLitSBomb:
5920 case wBait:
5921 case wWind:
5922 case wSSparkle:
5923 return 0;
5924
5925 case wFSparkle:
5926
5927 // Only take sparkle damage if the sparkle's parent item is not
5928 // defended against.
5929 if(enemyHitWeapon > -1)
5930 {
5931 int32_t p = 0;
5932 int32_t f = itemsbuf[enemyHitWeapon].family;
5933
5934 switch(f)
5935 {
5936 case itype_arrow:
5937 if(!candamage(p, edefARROW, w->unblockable)) return 0;
5938
5939 break;
5940
5941 case itype_cbyrna:
5942 if(!candamage(p, edefBYRNA, w->unblockable)) return 0;
5943
5944 break;
5945
5946 case itype_brang:
5947 if(!candamage(p, edefBRANG, w->unblockable)) return 0;
5948
5949 break;
5950
5951 default:
5952 return 0;
5953 }
5954 }
5955
5956 wpnId = wSword;
5957 power = game->get_hero_dmgmult()>>1;
5958 goto fsparkle;
5959 break;
5960
5961 case wBrang:
5962 {
5963 //int32_t def = defendNew(wpnId, &power, edefBRANG, w);
5964 281 int32_t def = defendNewInt(wpnId, &power, resolveEnemyDefence(w), w->unblockable, w);
5965 //preventing stunlock might be best, here. -Z
5966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 281 times.
281 if(def >= 0) return def;
5967
5968 // Not hurt by 0-damage weapons
5969
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 226 times.
281 if(!(flags & guy_bhit))
5970 {
5971 226 stunclk=160;
5972
5973
2/4
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 226 times.
226 if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))
5974 {
5975 hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))*game->get_hero_dmgmult();
5976 goto hitclock;
5977 }
5978
5979 226 break;
5980 }
5981
5982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 if(!power)
5983
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
55 hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_brang))*game->get_hero_dmgmult();
5984 else
5985 hp-=power;
5986
5987 55 goto hitclock;
5988 }
5989
5990 case wHookshot:
5991 {
5992 //int32_t def = defendNew(wpnId, &power, edefHOOKSHOT,w);
5993 int32_t def = defendNewInt(wpnId, &power, resolveEnemyDefence(w), w->unblockable, w);
5994
5995 if(def >= 0) return def;
5996
5997 bool swgrab = switch_hooked || w->family_class == itype_switchhook;
5998 if(swgrab || !(flags & guy_bhit))
5999 {
6000 if(!swgrab)
6001 stunclk=160;
6002
6003 if(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))
6004 {
6005 hp -= (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot))*game->get_hero_dmgmult();
6006 goto hitclock;
6007 }
6008
6009 break;
6010 }
6011
6012 if(!power) hp-=(enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].fam_type : current_item(itype_hookshot))*game->get_hero_dmgmult();
6013 else
6014 hp-=power;
6015
6016 goto hitclock;
6017 }
6018 break;
6019
6020 case wHSHandle:
6021 {
6022 if(itemsbuf[enemyHitWeapon>-1 ? enemyHitWeapon : current_item_id(itype_hookshot)].flags & ITEM_FLAG1)
6023 return 0;
6024
6025 bool ignorehookshot = ((defense[edefHOOKSHOT] == edIGNORE) || ((defense[edefHOOKSHOT] == edIGNOREL1 || defense[edefHOOKSHOT] == edSTUNORIGNORE)
6026 && (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_hookshot)) <= 0));
6027
6028 // Peahats, Darknuts, Aquamentuses, Pols Voices, Wizzrobes, Manhandlas
6029 if(!(family==eePEAHAT || family==eeAQUA || family==eeMANHAN || (family==eeWIZZ && !ignorehookshot)
6030 || (family==eeWALK && dmisc9==e9tPOLSVOICE) || (family==eeWALK && flags&(inv_back|inv_front|inv_left|inv_right))))
6031 return 0;
6032
6033 power = game->get_hero_dmgmult();
6034 }
6035
6036 fsparkle:
6037
6038 [[fallthrough]];
6039 default:
6040 // Work out the defenses!
6041 {
6042 326 int32_t def = defenditemclassNew(wpnId, &power, w);
6043
6044
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 326 times.
326 if(def >= 0)
6045 return def;
6046
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 else if(def == -2)
6047 {
6048 ret = 0;
6049 }
6050 }
6051
6052
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
652 if(!power)
6053 {
6054 if(flags & guy_bhit)
6055 hp-=1;
6056 else
6057 {
6058 // Don't make a long chain of 'stun' hits
6059 if((wpnId==wFire || wpnId==wBomb || wpnId==wSBomb || wpnId==wSword) && stunclk>0)
6060 return 1;
6061
6062
6063 if(!switch_hooked)
6064 stunclk=160;
6065 break;
6066 }
6067 }
6068 326 else hp-=power;
6069
6070 hitclock:
6071 381 hclk=33;
6072
6073 // Use w->dir instead of wpnDir to make sure boomerangs don't push enemies the wrong way
6074
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 225 times.
381 if((dir&2)==(w->dir&2))
6075 {
6076 225 sclk=(w->dir<<8)+16;
6077 225 }
6078 381 }
6079
6080
5/6
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 555 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 52 times.
607 if(((wpnId==wBrang) || (get_bit(quest_rules,qr_NOFLASHDEATH))) && (hp<=0 && !immortal))
6081 {
6082 52 fading=fade_blue_poof;
6083 52 }
6084
6085
6086 /*
6087 if( hitsfx > 0 ) //user set hit sound.
6088 {
6089 if ( !dying ) //Don't play the hit sound when dying.
6090 sfx(hitsfx, pan(int32_t(x)));
6091 }
6092 else sfx(WAV_EHIT, pan(int32_t(x))); //Don't play this one if the user sets a custom sound!
6093 */
6094 /*
6095 if( hitsfx > 0 ) //A sound is set.
6096 {
6097 if ( !dying ) //Don't play the hit sound when dying.
6098 sfx(hitsfx, pan(int32_t(x)));
6099 }
6100 */
6101
4/6
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 607 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 86 times.
✓ Branch 5 taken 521 times.
607 if ( FFCore.getQuestHeaderInfo(vZelda) > 0x250 || ( FFCore.getQuestHeaderInfo(vZelda) == 0x250 && FFCore.getQuestHeaderInfo(vBuild) > 31 )) //2.53 Gamma 2 and later
6102 {
6103
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
86 if( hitsfx > 0 ) //user-set hit sound.
6104 {
6105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86 times.
86 if (!dying) //don't play the hit sound on death! -Z
6106 86 sfx(hitsfx, pan(int32_t(x)));
6107 86 }
6108 else sfx(WAV_EHIT, pan(int32_t(x))); //Don't play the hardcoded sound if the user sets a custom one.
6109 86 }
6110 else //2.50.2 or earlier
6111 {
6112 521 sfx(WAV_EHIT, pan(int32_t(x)));
6113 521 sfx(hitsfx, pan(int32_t(x)));
6114 }
6115
2/2
✓ Branch 0 taken 606 times.
✓ Branch 1 taken 1 times.
607 if(family==eeGUY)
6116 1 sfx(WAV_EDEAD, pan(int32_t(x)));
6117
6118 // Penetrating weapons
6119
3/4
✓ Branch 0 taken 607 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 468 times.
✓ Branch 3 taken 139 times.
607 if((wpnId==wArrow || wpnId==wBeam) && !cannotpenetrate())
6120 {
6121 139 int32_t item=enemyHitWeapon;
6122
6123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139 times.
139 if(wpnId==wArrow)
6124 {
6125 //If we use an arrow type for the item's Weapon type, the flags differ, so we need to rely on the flags from an arrow class.
6126 if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG1) && (itemsbuf[parent_item].family == itype_arrow))
6127 return 0;
6128 else if(get_bit(quest_rules,qr_ARROWS_ALWAYS_PENETRATE)) return 0;
6129 //if(item<0)
6130 else
6131 item=current_item_id(itype_arrow);
6132 }
6133
6134 else
6135 {
6136
6137 //If we use an swordbeam type for the item's Weapon type, the flags differ, so we need to rely on the flags from an arrow class.
6138
2/6
✓ Branch 0 taken 139 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 139 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
139 if(item>=0 && (itemsbuf[item].flags&ITEM_FLAG3) && (itemsbuf[parent_item].family == itype_sword))
6139 return 0;
6140
6141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139 times.
139 else if(get_bit(quest_rules,qr_SWORDBEAMS_ALWAYS_PENETRATE)) return 0;
6142 else
6143 //if(item<0)
6144 139 item=current_item_id(itype_sword);
6145 }
6146 139 }
6147
6148 607 return ret;
6149 607 }
6150
6151 259672 bool enemy::dont_draw()
6152 {
6153
3/6
✓ Branch 0 taken 259672 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 259672 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 259672 times.
259672 if(fading==fade_invisible || (((flags2&guy_blinking)||(fading==fade_flicker)) && (clk&1)))
6154 return true;
6155
6156
2/2
✓ Branch 0 taken 1500 times.
✓ Branch 1 taken 258172 times.
259672 if(flags&guy_invisible)
6157 1500 return true;
6158
6159
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 258172 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
258172 if(flags&lens_only && !lensclk)
6160 return true;
6161
6162
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 258172 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
258172 if(lensclk && (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG6) && !(itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG7) &&
6163 !((flags&lens_only) && (get_bit(quest_rules,qr_LENSSEESENEMIES) || (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG5))))
6164 return true;
6165
6166 258172 return false;
6167 259672 }
6168
6169 #define DRAW_NORMAL 2
6170 #define DRAW_CLOAKED 1
6171 #define DRAW_INVIS 0
6172 // base drawing function to be used by all derived classes instead of
6173 // sprite::draw()
6174 227470 void enemy::draw(BITMAP *dest)
6175 {
6176
3/6
✓ Branch 0 taken 227470 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 227470 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 227470 times.
227470 if(fading==fade_invisible || (((flags2&guy_blinking)||(fading==fade_flicker)) && (clk&1)))
6177 return;
6178
2/2
✓ Branch 0 taken 412 times.
✓ Branch 1 taken 227058 times.
227470 if(flags&guy_invisible)
6179 412 return;
6180
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 227058 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
227058 if(lensclk && (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG6) && !(itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG7) && !(flags&lens_only))
6181 return;
6182
6183 //We did the normal don't_draw stuff here so we can make exceptions; specifically the lens check (which should make enemies
6184 // be cloaked if they have "invisible displays as cloaked" checked.
6185
6186 227058 byte canSee = DRAW_NORMAL;
6187 //Enemy specific stuff
6188
1/2
✓ Branch 0 taken 227058 times.
✗ Branch 1 not taken.
227058 if ( editorflags & ENEMY_FLAG1 )
6189 {
6190 canSee = DRAW_INVIS;
6191 if (editorflags & ENEMY_FLAG4) canSee = DRAW_CLOAKED;
6192 if (dmisc13 >= 0 && (editorflags & ENEMY_FLAG2))
6193 {
6194 if (game->item[dmisc13])
6195 {
6196 canSee = DRAW_NORMAL;
6197 }
6198 //else if ( lensclk && getlensid.flags SHOWINVIS )
6199 //{
6200 //
6201 //}
6202 //else
6203 //{
6204 // if ( (editorflags & ENEMY_FLAG4) ) canSee = DRAW_CLOAKED;
6205 // //otherwisem invisible
6206 //}
6207 }
6208 }
6209 //Room specific
6210
1/2
✓ Branch 0 taken 227058 times.
✗ Branch 1 not taken.
227058 if (tmpscr->flags3&fINVISROOM)
6211 {
6212 if (canSee == DRAW_NORMAL && !(current_item(itype_amulet)) &&
6213 !((itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG5) && lensclk) && family!=eeGANON) canSee = DRAW_CLOAKED;
6214 }
6215 //Lens check
6216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 227058 times.
227058 if (lensclk)
6217 {
6218 if((itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG6) && !(flags&lens_only))
6219 {
6220 if (canSee == DRAW_NORMAL)
6221 {
6222 if (itemsbuf[Hero.getLastLensID()].flags & ITEM_FLAG7) canSee = DRAW_CLOAKED;
6223 else canSee = DRAW_INVIS; //Should never happen cause dont_draw should catch this, but just in case.
6224 }
6225 }
6226 if(flags&lens_only)
6227 {
6228 if (canSee == DRAW_INVIS) canSee = DRAW_NORMAL;
6229 }
6230 }
6231 else
6232 {
6233
1/2
✓ Branch 0 taken 227058 times.
✗ Branch 1 not taken.
227058 if(flags&lens_only)
6234 canSee = DRAW_INVIS;
6235 }
6236
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 227058 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
227058 if (canSee == DRAW_INVIS && (editorflags & ENEMY_FLAG4)) canSee = DRAW_CLOAKED;
6237
2/4
✓ Branch 0 taken 227058 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 227058 times.
✗ Branch 3 not taken.
227058 if (canSee == DRAW_NORMAL && (editorflags & ENEMY_FLAG16)) canSee = DRAW_CLOAKED;
6238
6239
1/2
✓ Branch 0 taken 227058 times.
✗ Branch 1 not taken.
227058 if (canSee == DRAW_INVIS)
6240 return;
6241
6242
2/4
✓ Branch 0 taken 227058 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 227058 times.
227058 if(fallclk||drownclk)
6243 {
6244 if (canSee == DRAW_CLOAKED)
6245 {
6246 sprite::drawcloaked(dest);
6247 }
6248 else if (canSee == DRAW_NORMAL)
6249 {
6250 sprite::draw(dest);
6251 }
6252 return;
6253 }
6254 227058 int32_t cshold=cs;
6255
6256
2/2
✓ Branch 0 taken 6606 times.
✓ Branch 1 taken 220452 times.
227058 if(dying)
6257 {
6258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6606 times.
6606 if(clk2>=19)
6259 {
6260 if(!(clk2&2))
6261 {
6262 //if the enemy isn't totally invisible, or if it is, but Hero has the item needed to reveal it, draw it.
6263 if (canSee == DRAW_CLOAKED)
6264 {
6265 sprite::drawcloaked(dest);
6266 }
6267 else if (canSee == DRAW_NORMAL)
6268 {
6269 sprite::draw(dest);
6270 }
6271 }
6272 return;
6273 }
6274
6275 6606 flip = 0;
6276 6606 tile = wpnsbuf[spr_death].tile;
6277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6606 times.
6606 if ( do_animation )
6278 {
6279 6606 int32_t offs = 0;
6280
1/2
✓ Branch 0 taken 6606 times.
✗ Branch 1 not taken.
6606 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS))
6281 {
6282 if(clk2 > 2)
6283 {
6284 spr_death_anim_clk=0;
6285 clk2=1;
6286 if(hp > -1000)
6287 death_sfx();
6288 }
6289 if(clk2==1 && spr_death_anim_clk>-1)
6290 {
6291 ++clk2;
6292 spr_death_anim_frm=(spr_death_anim_clk/zc_max(wpnsbuf[spr_death].speed,1));
6293 spr_death_anim_frm *= zc_max(1,txsz);
6294 int32_t rows = TILEROW(tile+spr_death_anim_frm)-TILEROW(tile);
6295 spr_death_anim_frm += TILES_PER_ROW*(zc_min(0,tysz-1)*rows);
6296 if(++spr_death_anim_clk >= (zc_max(wpnsbuf[spr_death].speed,1) * zc_max(wpnsbuf[spr_death].frames,1)))
6297 {
6298 spr_death_anim_clk=-1;
6299 clk2=1;
6300 }
6301 }
6302 tile += spr_death_anim_frm;
6303 }
6304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6606 times.
6606 else if(BSZ)
6305 {
6306 offs = zc_min((15-clk2)/3,4);
6307 }
6308
4/4
✓ Branch 0 taken 4234 times.
✓ Branch 1 taken 2372 times.
✓ Branch 2 taken 2122 times.
✓ Branch 3 taken 2112 times.
6606 else if(clk2>6 && clk2<=12)
6309 {
6310 2112 offs = 1;
6311 2112 }
6312
6313
2/2
✓ Branch 0 taken 4494 times.
✓ Branch 1 taken 2112 times.
6606 if(offs)
6314 {
6315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2112 times.
2112 offs *= zc_max(1,txsz);
6316 2112 int32_t rows = TILEROW(tile+offs)-TILEROW(tile);
6317
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2112 times.
2112 offs += TILES_PER_ROW*(zc_min(0,tysz-1)*rows);
6318 2112 }
6319 6606 tile += offs;
6320 6606 }
6321
6322
4/6
✓ Branch 0 taken 6606 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6606 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2078 times.
✓ Branch 5 taken 4528 times.
6606 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS) || BSZ || fading==fade_blue_poof)
6323 2078 cs = wpnsbuf[spr_death].csets&15;
6324 else
6325 4528 cs = (((clk2+5)>>1)&3)+6;
6326 6606 }
6327
3/4
✓ Branch 0 taken 5335 times.
✓ Branch 1 taken 215117 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5335 times.
220452 else if(hclk>0 && getCanFlicker())
6328 {
6329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5335 times.
5335 if(family==eeGANON)
6330 cs=(((hclk-1)>>1)&3)+6;
6331
3/4
✓ Branch 0 taken 4830 times.
✓ Branch 1 taken 505 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4830 times.
5335 else if(hclk<33 && !get_bit(quest_rules,qr_ENEMIESFLICKER))
6332 4830 cs=(((hclk-1)>>1)&3)+6;
6333 5335 }
6334 //draw every other frame for flickering enemies
6335
8/10
✓ Branch 0 taken 113579 times.
✓ Branch 1 taken 113479 times.
✓ Branch 2 taken 113579 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5973 times.
✓ Branch 5 taken 107606 times.
✓ Branch 6 taken 172 times.
✓ Branch 7 taken 5801 times.
✓ Branch 8 taken 172 times.
✗ Branch 9 not taken.
227058 if((frame&1)==1 || !(family !=eeGANON && hclk>0 && get_bit(quest_rules,qr_ENEMIESFLICKER) && getCanFlicker()))
6336 {
6337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 226886 times.
226886 if (canSee == DRAW_CLOAKED)
6338 {
6339 sprite::drawcloaked(dest);
6340 }
6341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 226886 times.
226886 else if (canSee == DRAW_NORMAL)
6342 {
6343
1/2
✓ Branch 0 taken 226886 times.
✗ Branch 1 not taken.
226886 if ( frozenclock < 0 )
6344 {
6345 if ( frozentile > 0 ) tile = frozentile;
6346 loadpalset(csBOSS,frozencset);
6347 }
6348 226886 sprite::draw(dest);
6349 226886 }
6350 226886 }
6351 227058 cs=cshold;
6352 227470 }
6353
6354 //old zc bosses
6355 165500 void enemy::drawzcboss(BITMAP *dest)
6356 {
6357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 165500 times.
165500 if(dont_draw())
6358 return;
6359
6360 165500 int32_t cshold=cs;
6361
6362
2/2
✓ Branch 0 taken 6444 times.
✓ Branch 1 taken 159056 times.
165500 if(dying)
6363 {
6364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6444 times.
6444 if(clk2>=19)
6365 {
6366 if(!(clk2&2))
6367 sprite::drawzcboss(dest);
6368
6369 return;
6370 }
6371
6372 6444 flip = 0;
6373 6444 tile = wpnsbuf[spr_death].tile;
6374
6375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6444 times.
6444 if ( do_animation )
6376 {
6377
1/2
✓ Branch 0 taken 6444 times.
✗ Branch 1 not taken.
6444 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS))
6378 {
6379 if(clk2 > 2)
6380 {
6381 spr_death_anim_clk=0;
6382 clk2=1;
6383 if(hp > -1000)
6384 death_sfx();
6385 }
6386 if(clk2==1 && spr_death_anim_clk>-1)
6387 {
6388 ++clk2;
6389 spr_death_anim_frm=(spr_death_anim_clk/zc_max(wpnsbuf[spr_death].speed,1));
6390 spr_death_anim_frm *= zc_max(1,txsz);
6391 int32_t rows = TILEROW(tile+spr_death_anim_frm)-TILEROW(tile);
6392 spr_death_anim_frm += TILES_PER_ROW*(zc_min(0,tysz-1)*rows);
6393 if(++spr_death_anim_clk >= (zc_max(wpnsbuf[spr_death].speed,1) * zc_max(wpnsbuf[spr_death].frames,1)))
6394 {
6395 spr_death_anim_clk=-1;
6396 clk2=1;
6397 }
6398 }
6399 tile += spr_death_anim_frm;
6400 }
6401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6444 times.
6444 else if(BSZ)
6402 tile += zc_min((15-clk2)/3,4);
6403
4/4
✓ Branch 0 taken 4126 times.
✓ Branch 1 taken 2318 times.
✓ Branch 2 taken 2068 times.
✓ Branch 3 taken 2058 times.
6444 else if(clk2>6 && clk2<=12)
6404 2058 ++tile;
6405 6444 }
6406
6407
4/6
✓ Branch 0 taken 6444 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6444 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1916 times.
✓ Branch 5 taken 4528 times.
6444 if(!get_bit(quest_rules,qr_HARDCODED_ENEMY_ANIMS) || BSZ || fading==fade_blue_poof)
6408 1916 cs = wpnsbuf[spr_death].csets&15;
6409 else
6410 4528 cs = (((clk2+5)>>1)&3)+6;
6411 6444 }
6412
2/2
✓ Branch 0 taken 153067 times.
✓ Branch 1 taken 5989 times.
159056 else if(hclk>0)
6413 {
6414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5989 times.
5989 if(family==eeGANON)
6415 cs=(((hclk-1)>>1)&3)+6;
6416
3/4
✓ Branch 0 taken 5470 times.
✓ Branch 1 taken 519 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5470 times.
5989 else if(hclk<33 && !get_bit(quest_rules,qr_ENEMIESFLICKER))
6417 5470 cs=(((hclk-1)>>1)&3)+6;
6418 5989 }
6419
6420
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 165500 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
165500 if((tmpscr->flags3&fINVISROOM) &&
6421 !(current_item(itype_amulet)) &&
6422 !(get_bit(quest_rules,qr_LENSSEESENEMIES) &&
6423 lensclk) && family!=eeGANON)
6424 {
6425 sprite::drawcloaked(dest);
6426 }
6427 else
6428 {
6429
5/6
✓ Branch 0 taken 165500 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12433 times.
✓ Branch 3 taken 153067 times.
✓ Branch 4 taken 12263 times.
✓ Branch 5 taken 170 times.
165500 if(family !=eeGANON && hclk>0 && get_bit(quest_rules,qr_ENEMIESFLICKER))
6430 {
6431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170 times.
170 if((frame&1)==1)
6432 170 sprite::drawzcboss(dest);
6433 170 }
6434 else
6435 165330 sprite::drawzcboss(dest);
6436 }
6437
6438 165500 cs=cshold;
6439 165500 }
6440
6441
6442 // similar to the overblock function--can do up to a 32x32 sprite
6443 //will this play nicely with scripttile, solely using the modifications in sprite::draw()?
6444 396 void enemy::drawblock(BITMAP *dest,int32_t mask)
6445 {
6446 396 int32_t thold=tile;
6447 396 int32_t t1=tile;
6448 396 int32_t t2=tile+20;
6449 396 int32_t t3=tile+1;
6450 396 int32_t t4=tile+21;
6451
6452
1/5
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 396 times.
396 switch(mask)
6453 {
6454 case 1:
6455 enemy::drawzcboss(dest);
6456 break;
6457
6458 case 3:
6459 if(flip&2)
6460 zc_swap(t1,t2);
6461
6462 tile=t1;
6463 enemy::drawzcboss(dest);
6464 tile=t2;
6465 yofs+=16;
6466 enemy::drawzcboss(dest);
6467 yofs-=16;
6468 break;
6469
6470 case 5:
6471 t2=tile+1;
6472
6473 if(flip&1)
6474 zc_swap(t1,t2);
6475
6476 tile=t1;
6477 enemy::drawzcboss(dest);
6478 tile=t2;
6479 xofs+=16;
6480 enemy::drawzcboss(dest);
6481 xofs-=16;
6482 break;
6483
6484 case 15:
6485
1/2
✓ Branch 0 taken 396 times.
✗ Branch 1 not taken.
396 if(flip&1)
6486 {
6487 zc_swap(t1,t3);
6488 zc_swap(t2,t4);
6489 }
6490
6491
1/2
✓ Branch 0 taken 396 times.
✗ Branch 1 not taken.
396 if(flip&2)
6492 {
6493 zc_swap(t1,t2);
6494 zc_swap(t3,t4);
6495 }
6496
6497 396 tile=t1;
6498 396 enemy::drawzcboss(dest);
6499 396 tile=t2;
6500 396 yofs+=16;
6501 396 enemy::drawzcboss(dest);
6502 396 yofs-=16;
6503 396 tile=t3;
6504 396 xofs+=16;
6505 396 enemy::drawzcboss(dest);
6506 396 tile=t4;
6507 396 yofs+=16;
6508 396 enemy::drawzcboss(dest);
6509 396 xofs-=16;
6510 396 yofs-=16;
6511 396 break;
6512 }
6513
6514 396 tile=thold;
6515 396 }
6516
6517 94172 void enemy::drawshadow(BITMAP *dest, bool translucent)
6518 {
6519
4/4
✓ Branch 0 taken 92672 times.
✓ Branch 1 taken 1500 times.
✓ Branch 2 taken 24300 times.
✓ Branch 3 taken 68372 times.
94172 if(dont_draw() || isSideViewGravity())
6520 {
6521 25800 return;
6522 }
6523
6524
2/2
✓ Branch 0 taken 1278 times.
✓ Branch 1 taken 67094 times.
68372 if(dying)
6525 {
6526 1278 return;
6527 }
6528
6529
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 67094 times.
✓ Branch 2 taken 5118 times.
✓ Branch 3 taken 61976 times.
67094 if(((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))||
6530 67094 (darkroom))
6531 {
6532 5118 return;
6533 }
6534 else
6535 {
6536
4/4
✓ Branch 0 taken 61084 times.
✓ Branch 1 taken 892 times.
✓ Branch 2 taken 60942 times.
✓ Branch 3 taken 142 times.
61976 if(enemycanfall(id, false) && shadowtile == 0)
6537 142 shadowtile = wpnsbuf[spr_shadow].tile;
6538
6539
5/6
✓ Branch 0 taken 58233 times.
✓ Branch 1 taken 3743 times.
✓ Branch 2 taken 58233 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 57341 times.
✓ Branch 5 taken 892 times.
61976 if(z>0 || fakez>0 || !enemycanfall(id, false))
6540 {
6541
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4635 times.
4635 if(!shadow_overpit(this))
6542 4635 sprite::drawshadow(dest,translucent);
6543 4635 }
6544 }
6545 94172 }
6546
6547 3213 void enemy::masked_draw(BITMAP *dest,int32_t mx,int32_t my,int32_t mw,int32_t mh)
6548 {
6549 3213 BITMAP *sub=create_sub_bitmap(dest,mx,my,mw,mh);
6550
6551
1/2
✓ Branch 0 taken 3213 times.
✗ Branch 1 not taken.
3213 if(sub!=NULL)
6552 {
6553 3213 xofs-=mx;
6554 3213 yofs-=my;
6555 3213 enemy::draw(sub);
6556 3213 xofs+=mx;
6557 3213 yofs+=my;
6558 3213 destroy_bitmap(sub);
6559 3213 }
6560 else
6561 enemy::draw(dest);
6562 3213 }
6563
6564 // override hit detection to check for invicibility, stunned, etc
6565 bool enemy::hit(sprite *s)
6566 {
6567 if(!(s->scriptcoldet&1) || s->fallclk || s->drownclk) return false;
6568
6569 return (dying || hclk>0) ? false : sprite::hit(s);
6570 }
6571
6572 207237 bool enemy::hit(int32_t tx,int32_t ty,int32_t tz,int32_t txsz2,int32_t tysz2,int32_t tzsz2)
6573 {
6574
4/4
✓ Branch 0 taken 201945 times.
✓ Branch 1 taken 5292 times.
✓ Branch 2 taken 196740 times.
✓ Branch 3 taken 5205 times.
207237 return (dying || hclk>0) ? false : sprite::hit(tx,ty,tz,txsz2,tysz2,tzsz2);
6575 }
6576 bool enemy::hit(int32_t tx,int32_t ty,int32_t txsz2,int32_t tysz2)
6577 {
6578 return (dying || hclk>0) ? false : sprite::hit(tx,ty,txsz2,tysz2);
6579 }
6580
6581 20536 bool enemy::hit(weapon *w)
6582 {
6583
3/6
✓ Branch 0 taken 20536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20536 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 20536 times.
20536 if(!(w->scriptcoldet&1) || w->fallclk || w->drownclk) return false;
6584
6585
4/4
✓ Branch 0 taken 19543 times.
✓ Branch 1 taken 993 times.
✓ Branch 2 taken 18954 times.
✓ Branch 3 taken 589 times.
20536 return (dying || hclk>0) ? false : sprite::hit(w);
6586 20536 }
6587
6588 110499 bool enemy::can_pitfall(bool checkspawning)
6589 {
6590
4/4
✓ Branch 0 taken 110489 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 109536 times.
✓ Branch 3 taken 963 times.
110499 if((fading||isspawning)&&checkspawning) return false; //Don't fall during spawn.
6591
2/2
✓ Branch 0 taken 109492 times.
✓ Branch 1 taken 44 times.
109536 switch(guysbuf[id&0xFFF].family)
6592 {
6593 case eeAQUA:
6594 case eeDIG:
6595 case eeDONGO:
6596 case eeFAIRY:
6597 case eeGANON:
6598 case eeGHOMA:
6599 case eeGLEEOK:
6600 case eeGUY:
6601 case eeLANM:
6602 case eeMANHAN:
6603 case eeMOLD:
6604 case eeNONE:
6605 case eePATRA:
6606 case eeZORA:
6607 44 return false; //Disallowed types
6608 default:
6609 109492 return true;
6610 }
6611 110499 }
6612 //Handle death
6613 192390 void enemy::try_death(bool force_kill)
6614 {
6615
5/8
✓ Branch 0 taken 192390 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 192390 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 248 times.
✓ Branch 5 taken 192142 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 248 times.
192390 if(!dying && (force_kill || (hp<=0 && !immortal)))
6616 {
6617 248 std::vector<int32_t> &ev = FFCore.eventData;
6618 248 ev.clear();
6619 248 ev.push_back(10000);
6620 248 ev.push_back(getUID());
6621
6622 248 throwGenScriptEvent(GENSCR_EVENT_ENEMY_DEATH);
6623 248 bool isSaved = !ev[0];
6624 248 ev.clear();
6625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 248 times.
248 if(isSaved) return;
6626
6627
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
248 if(itemguy && (hasitem&2)!=0)
6628 {
6629
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for(int32_t i=0; i<items.Count(); i++)
6630 {
6631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(((item*)items.spr(i))->pickup&ipENEMY)
6632 {
6633
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!get_bit(quest_rules, qr_BROKEN_ITEM_CARRYING))
6634 {
6635 if (get_bit(quest_rules, qr_ENEMY_DROPS_USE_HITOFFSETS))
6636 {
6637 items.spr(i)->x = x+hxofs+(hxsz/2)-8;
6638 items.spr(i)->y = y+hyofs+(hysz/2)-10-fakez;
6639 }
6640 else
6641 {
6642 if(extend >= 3)
6643 {
6644 items.spr(i)->x = x+(txsz-1)*8;
6645 items.spr(i)->y = y-2+(tysz-1)*8;
6646 }
6647 else
6648 {
6649 items.spr(i)->x = x;
6650 items.spr(i)->y = y - 2;
6651 }
6652 }
6653 items.spr(i)->z = z;
6654 items.spr(i)->fakez = fakez;
6655 }
6656 else
6657 {
6658 3 items.spr(i)->x = x;
6659 3 items.spr(i)->y = y - 2;
6660 }
6661 3 }
6662 3 }
6663 3 }
6664
6665 248 dying=true;
6666
6667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 248 times.
248 if(fading==fade_flash_die)
6668 clk2=19+18*4;
6669 else
6670 {
6671 248 clk2 = BSZ ? 15 : 19;
6672
6673
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 196 times.
248 if(fading!=fade_blue_poof)
6674 196 fading=0;
6675 }
6676
6677
2/2
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 3 times.
248 if(itemguy)
6678 {
6679 3 hasitem&=~2;
6680 3 item_set=0;
6681 3 }
6682
6683
4/6
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 243 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 243 times.
248 if(currscr<128 && count_enemy && !script_spawned)
6684 243 game->guys[(currmap<<7)+currscr]-=1;
6685 248 }
6686 192390 }
6687
6688 // --==**==--
6689
6690 // Movement routines that can be used by derived classes as needed
6691
6692 // --==**==--
6693
6694 4408 void enemy::fix_coords(bool bound)
6695 {
6696
1/2
✓ Branch 0 taken 4408 times.
✗ Branch 1 not taken.
4408 if ((get_bit(quest_rules,qr_OUTOFBOUNDSENEMIES) ? 1 : 0) ^ ((editorflags&ENEMY_FLAG11)?1:0)) return;
6697
1/2
✓ Branch 0 taken 4408 times.
✗ Branch 1 not taken.
4408 if(moveflags & FLAG_IGNORE_SCREENEDGE) bound = false;
6698
6699
6700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4408 times.
4408 if(bound)
6701 {
6702
1/2
✓ Branch 0 taken 4408 times.
✗ Branch 1 not taken.
4408 if ( ((unsigned)(id&0xFFF)) < MAXGUYS )
6703 {
6704
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4408 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4408 x=vbound(x, 0, (( guysbuf[id].SIZEflags&guyflagOVERRIDE_TILE_WIDTH && !isflier(id) ) ? (256-((txsz-1)*16)) : 240));
6705
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4408 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4408 y=vbound(y, 0,(( guysbuf[id].SIZEflags&guyflagOVERRIDE_TILE_HEIGHT && !isflier(id) ) ? (176-((txsz-1)*16)) : 160));
6706 4408 }
6707 else
6708 {
6709 x=vbound(x, 0,240);
6710 y=vbound(y, 0,160);
6711 }
6712 4408 }
6713
6714
6/10
✓ Branch 0 taken 3464 times.
✓ Branch 1 taken 944 times.
✓ Branch 2 taken 4408 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4408 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4408 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 4408 times.
4408 if(!OUTOFBOUNDS)
6715 {
6716 /*x=((int32_t(x)&0xF0)+((int32_t(x)&8)?16:0));
6717
6718 if(isSideViewGravity())
6719 y=((int32_t(y)&0xF8)+((int32_t(y)&4)?8:0));
6720 else
6721 y=((int32_t(y)&0xF0)+((int32_t(y)&8)?16:0));
6722 */
6723 4408 do_fix(x, 16, true);
6724
2/2
✓ Branch 0 taken 944 times.
✓ Branch 1 taken 3464 times.
4408 if(isSideViewGravity())
6725 944 do_fix(y,8,true);
6726 3464 else do_fix(y,16,true);
6727 4408 }
6728 4408 }
6729 151 bool enemy::cannotpenetrate()
6730 {
6731
3/4
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 139 times.
151 return (family == eeAQUA || family == eeMANHAN || family == eeGHOMA);
6732 }
6733
6734 bool enemy::canmove_old(int32_t ndir,zfix s,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
6735 {
6736 bool ok;
6737 int32_t dx = 0, dy = 0;
6738 int32_t sv = 8;
6739
6740 //Why is this here??? Why is it needed???
6741 s += 0.5; // Make the ints round; doesn't seem to cause any problems.
6742
6743 switch(ndir)
6744 {
6745 case 8:
6746 case up:
6747 if(canfall(id) && isSideViewGravity())
6748 return false;
6749
6750 dy = dy1-s;
6751 special = (special==spw_clipbottomright)?spw_none:special;
6752 ok = !m_walkflag_old(x,y+dy,special, x, y) && !flyerblocked(x,y+dy, special);
6753 break;
6754
6755 case 12:
6756 case down:
6757 if(canfall(id) && isSideViewGravity())
6758 return false;
6759
6760 dy = dy2+s;
6761 ok = !m_walkflag_old(x,y+dy,special, x, y) && !flyerblocked(x,y+dy, special);
6762 break;
6763
6764 case 14:
6765 case left:
6766 dx = dx1-s;
6767 sv = ((isSideViewGravity())?7:8);
6768 special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
6769 ok = !m_walkflag_old(x+dx,y+sv,special, x, y) && !flyerblocked(x+dx,y+8, special);
6770 break;
6771
6772 case 10:
6773 case right:
6774 dx = dx2+s;
6775 sv = ((isSideViewGravity())?7:8);
6776 ok = !m_walkflag_old(x+dx,y+sv,special, x, y) && !flyerblocked(x+dx,y+8, special);
6777 break;
6778
6779 case 9:
6780 case r_up:
6781 dx = dx2+s;
6782 dy = dy1-s;
6783 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6784 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6785 break;
6786
6787 case 11:
6788 case r_down:
6789 dx = dx2+s;
6790 dx = dy2+s;
6791 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6792 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6793 break;
6794
6795 case 13:
6796 case l_down:
6797 dx = dx1-s;
6798 dy = dy2+s;
6799 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6800 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6801 break;
6802
6803 case 15:
6804 case l_up:
6805 dx = dx1-s;
6806 dy = dy1-s;
6807 ok = !m_walkflag_old(x,y+dy,special, x, y) && !m_walkflag_old(x+dx,y+sv,special, x, y) &&
6808 !flyerblocked(x,y+dy, special) && !flyerblocked(x+dx,y+8, special);
6809 break;
6810
6811 default:
6812 db=99;
6813 return true;
6814 }
6815
6816 return ok;
6817 }
6818
6819
6820
6821
6822 // returns true if next step is ok, false if there is something there
6823 37069 bool enemy::canmove(int32_t ndir,zfix s,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2, bool kb)
6824 {
6825 37069 bool ok = false; //initialise the var, son't just declare it
6826 37069 int32_t dx = 0, dy = 0;
6827 37069 int32_t sv = 8;
6828 37069 int32_t tries = 2; int32_t try_x = 0; int32_t try_y = 0;
6829 //Why is this here??? Why is it needed???
6830 37069 s += 0.5; // Make the ints round; doesn't seem to cause any problems.
6831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37069 times.
37069 int32_t usexoffs = (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) ? hxofs : 0;
6832
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37069 times.
37069 int32_t useyoffs = (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) ? hyofs : 0;
6833
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37069 times.
37069 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
6834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37069 times.
37069 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
6835 37069 bool offgrid = OFFGRID_ENEMY;
6836
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37069 times.
37069 if(!offgrid)
6837 {
6838 //Enemies smaller than 1-tile must act as 1-tile large, if off-grid movement is disabled.
6839
1/2
✓ Branch 0 taken 37069 times.
✗ Branch 1 not taken.
37069 if(usehei<16)usehei=16;
6840
1/2
✓ Branch 0 taken 37069 times.
✗ Branch 1 not taken.
37069 if(usewid<16)usewid=16;
6841 37069 }
6842
8/9
✓ Branch 0 taken 5952 times.
✓ Branch 1 taken 5491 times.
✓ Branch 2 taken 6422 times.
✓ Branch 3 taken 5913 times.
✓ Branch 4 taken 2996 times.
✓ Branch 5 taken 4534 times.
✓ Branch 6 taken 3584 times.
✓ Branch 7 taken 2177 times.
✗ Branch 8 not taken.
37069 switch(ndir) //need to check every 8 pixels between two points
6843 {
6844 case 8:
6845 case up:
6846 {
6847
4/4
✓ Branch 0 taken 1689 times.
✓ Branch 1 taken 4263 times.
✓ Branch 2 taken 1498 times.
✓ Branch 3 taken 191 times.
5952 if(enemycanfall(id) && isSideViewGravity())
6848 191 return false;
6849
6850 5761 dy = dy1-s;
6851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5761 times.
5761 special = (special==spw_clipbottomright)?spw_none:special;
6852 5761 tries = usewid/(offgrid ? 8 : 16);
6853 //Z_eventlog("Trying move UP, dy=%d,usewid=%d,usehei=%d\n",int32_t(dy),usewid,usehei);
6854
2/2
✓ Branch 0 taken 5028 times.
✓ Branch 1 taken 5761 times.
10789 for ( ; tries > 0; --tries )
6855 {
6856
2/2
✓ Branch 0 taken 720 times.
✓ Branch 1 taken 5041 times.
5761 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy,special, ndir, x+usexoffs+try_x, y+useyoffs, kb) && !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy, special,kb);
6857 5761 try_x += (offgrid ? 8 : 16);
6858
2/2
✓ Branch 0 taken 5028 times.
✓ Branch 1 taken 733 times.
5761 if (!ok) break;
6859 5028 }
6860
2/2
✓ Branch 0 taken 5028 times.
✓ Branch 1 taken 733 times.
5761 if(!ok) break;
6861
1/2
✓ Branch 0 taken 5028 times.
✗ Branch 1 not taken.
5028 if((usewid%16)>0) //Uneven width
6862 {
6863 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy,special, ndir, x+usexoffs+usewid-1, y+useyoffs, kb) && !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy, special,kb);
6864 }
6865 5028 break;
6866 }
6867 case 12:
6868 case down:
6869 {
6870
4/4
✓ Branch 0 taken 1703 times.
✓ Branch 1 taken 3788 times.
✓ Branch 2 taken 1485 times.
✓ Branch 3 taken 218 times.
5491 if(enemycanfall(id) && isSideViewGravity())
6871 218 return false;
6872
6873 5273 dy = dy2+s;
6874 5273 tries = usewid/(offgrid ? 8 : 16);
6875 //Z_eventlog("Trying move DOWN, dy=%d,usewid=%d,usehei=%d\n",int32_t(dy),usewid,usehei);
6876
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 5273 times.
9838 for ( ; tries > 0; --tries )
6877 {
6878
3/4
✓ Branch 0 taken 708 times.
✓ Branch 1 taken 4565 times.
✓ Branch 2 taken 4565 times.
✗ Branch 3 not taken.
5273 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy,special, ndir, x+usexoffs+try_x, y+useyoffs, kb) && !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+zc_max(usehei-16,0), special,kb);
6879 5273 try_x += (offgrid ? 8 : 16);
6880
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 708 times.
5273 if (!ok) break;
6881 4565 }
6882
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 708 times.
5273 if(!ok) break;
6883
1/2
✓ Branch 0 taken 4565 times.
✗ Branch 1 not taken.
4565 if((usewid%16)>0) //Uneven width
6884 {
6885 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy,special, ndir, x+usexoffs+usewid-1, y+useyoffs, kb) && !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+zc_max(usehei-16,0), special,kb);
6886 }
6887 4565 break;
6888 }
6889 case 14:
6890 case left:
6891 {
6892 6422 dx = dx1-s;
6893 6422 sv = ((isSideViewGravity())?7:0);
6894
3/4
✓ Branch 0 taken 6422 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 6421 times.
6422 special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
6895 6422 tries = usehei/(offgrid ? 8 : 16);
6896 //Z_eventlog("Trying move LEFT, dx=%d,usewid=%d,usehei=%d\n",int32_t(dx),usewid,usehei);
6897
2/2
✓ Branch 0 taken 5722 times.
✓ Branch 1 taken 6422 times.
12144 for ( ; tries > 0; --tries )
6898 {
6899
2/2
✓ Branch 0 taken 697 times.
✓ Branch 1 taken 5725 times.
6422 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+try_y+sv,special, ndir, x+usexoffs, y+useyoffs+try_y, kb) && !flyerblocked(x+usexoffs+dx,y+8+useyoffs+try_y, special,kb);
6900 6422 try_y += (offgrid ? 8 : 16);
6901
2/2
✓ Branch 0 taken 5722 times.
✓ Branch 1 taken 700 times.
6422 if (!ok) break;
6902 5722 }
6903
2/2
✓ Branch 0 taken 5722 times.
✓ Branch 1 taken 700 times.
6422 if(!ok) break;
6904
1/2
✓ Branch 0 taken 5722 times.
✗ Branch 1 not taken.
5722 if((usehei%16)>0) //Uneven height
6905 {
6906 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+usehei-1+sv,special, ndir, x+usexoffs, y+useyoffs+usehei-1, kb) && !flyerblocked(x+usexoffs+dx,y+8+useyoffs+usehei-1, special,kb);
6907 }
6908 5722 break;
6909 }
6910 case 10:
6911 case right:
6912 {
6913 5913 dx = dx2+s;
6914 5913 sv = ((isSideViewGravity())?7:0);
6915 5913 tries = usehei/(offgrid ? 8 : 16);
6916 //Z_eventlog("Trying move RIGHT, dx=%d,usewid=%d,usehei=%d\n",int32_t(dx),usewid,usehei);
6917
2/2
✓ Branch 0 taken 5075 times.
✓ Branch 1 taken 5913 times.
10988 for ( ; tries > 0; --tries )
6918 {
6919
3/4
✓ Branch 0 taken 833 times.
✓ Branch 1 taken 5080 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5080 times.
5913 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+try_y+sv,special, ndir, x+usexoffs, y+useyoffs+try_y, kb) && !flyerblocked(x+usexoffs+dx+zc_max(usewid-16,0),y+8+useyoffs+try_y, special,kb);
6920 5913 try_y += (offgrid ? 8 : 16);
6921
2/2
✓ Branch 0 taken 5075 times.
✓ Branch 1 taken 838 times.
5913 if (!ok) break;
6922 5075 }
6923
2/2
✓ Branch 0 taken 5075 times.
✓ Branch 1 taken 838 times.
5913 if(!ok) break;
6924
1/2
✓ Branch 0 taken 5075 times.
✗ Branch 1 not taken.
5075 if((usehei%16)>0) //Uneven height
6925 {
6926 ok = !m_walkflag(x+usexoffs+dx,y+useyoffs+usehei-1+sv,special, ndir, x+usexoffs, y+useyoffs+usehei-1, kb) && !flyerblocked(x+usexoffs+dx+zc_max(usewid-16,0),y+8+useyoffs+usehei-1, special,kb);
6927 }
6928 5075 break;
6929 }
6930 case 9:
6931 case r_up:
6932 {
6933 2996 dx = dx2+s;
6934 2996 dy = dy1-s;
6935 2996 int32_t tries_x = usewid/(offgrid ? 8 : 16);
6936 2996 sv = ((isSideViewGravity())?7:0);
6937
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 2996 times.
5905 for ( ; tries_x > 0; --tries_x )
6938 {
6939 2996 int32_t tries_y = usehei/(offgrid ? 8 : 16);
6940 2996 try_y = 0;
6941
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 2996 times.
5905 for ( ; tries_y > 0; --tries_y )
6942 {
6943
4/4
✓ Branch 0 taken 2949 times.
✓ Branch 1 taken 47 times.
✓ Branch 2 taken 2932 times.
✓ Branch 3 taken 17 times.
5928 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
6944
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2916 times.
2932 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
6945 2996 try_y += (offgrid ? 8 : 16);
6946
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 87 times.
2996 if (!ok) break;
6947 2909 }
6948
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 87 times.
2996 if (!ok) break;
6949
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2909 times.
2909 if((usehei%16)>0) //Uneven height
6950 {
6951 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
6952 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
6953 }
6954 2909 try_x += (offgrid ? 8 : 16);
6955 2909 }
6956
2/2
✓ Branch 0 taken 2909 times.
✓ Branch 1 taken 87 times.
2996 if(!ok) break;
6957
1/2
✓ Branch 0 taken 2909 times.
✗ Branch 1 not taken.
2909 if((usewid%16)>0) //Uneven width
6958 {
6959 int32_t tries_y = usehei/(offgrid ? 8 : 16);
6960 try_y = 0;
6961 for ( ; tries_y > 0; --tries_y )
6962 {
6963 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
6964 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
6965 try_y += (offgrid ? 8 : 16);
6966 if (!ok) break;
6967 }
6968 if (!ok) break;
6969 if((usehei%16)>0) //Uneven height
6970 {
6971 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
6972 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
6973 }
6974 }
6975 2909 break;
6976 }
6977 case 11:
6978 case r_down:
6979 {
6980 4534 dx = dx2+s;
6981 4534 dx = dy2+s;
6982 4534 int32_t tries_x = usewid/(offgrid ? 8 : 16);
6983 //sv = ((isSideViewGravity())?7:0);
6984
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 4534 times.
8991 for ( ; tries_x > 0; --tries_x )
6985 {
6986 4534 int32_t tries_y = usehei/(offgrid ? 8 : 16);
6987 4534 try_y = 0;
6988
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 4534 times.
8991 for ( ; tries_y > 0; --tries_y )
6989 {
6990
3/4
✓ Branch 0 taken 4534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4457 times.
✓ Branch 3 taken 77 times.
8991 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
6991
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4457 times.
4457 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
6992 4534 try_y += (offgrid ? 8 : 16);
6993
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 77 times.
4534 if (!ok) break;
6994 4457 }
6995
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 77 times.
4534 if (!ok) break;
6996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4457 times.
4457 if((usehei%16)>0) //Uneven height
6997 {
6998 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
6999 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
7000 }
7001 4457 try_x += (offgrid ? 8 : 16);
7002 4457 }
7003
2/2
✓ Branch 0 taken 4457 times.
✓ Branch 1 taken 77 times.
4534 if(!ok) break;
7004
1/2
✓ Branch 0 taken 4457 times.
✗ Branch 1 not taken.
4457 if((usewid%16)>0) //Uneven width
7005 {
7006 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7007 try_y = 0;
7008 for ( ; tries_y > 0; --tries_y )
7009 {
7010 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
7011 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
7012 try_y += (offgrid ? 8 : 16);
7013 if (!ok) break;
7014 }
7015 if (!ok) break;
7016 if((usehei%16)>0) //Uneven height
7017 {
7018 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
7019 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
7020 }
7021 }
7022 4457 break;
7023 }
7024 case 13:
7025 case l_down:
7026 {
7027 3584 dx = dx1-s;
7028 3584 dy = dy2+s;
7029 3584 int32_t tries_x = usewid/(offgrid ? 8 : 16);
7030 //sv = ((isSideViewGravity())?7:0);
7031
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 3584 times.
7119 for ( ; tries_x > 0; --tries_x )
7032 {
7033 3584 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7034 3584 try_y = 0;
7035
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 3584 times.
7119 for ( ; tries_y > 0; --tries_y )
7036 {
7037
4/4
✓ Branch 0 taken 3553 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 3535 times.
✓ Branch 3 taken 18 times.
7119 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
7038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3535 times.
3535 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
7039 3584 try_y += (offgrid ? 8 : 16);
7040
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 49 times.
3584 if (!ok) break;
7041 3535 }
7042
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 49 times.
3584 if (!ok) break;
7043
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3535 times.
3535 if((usehei%16)>0) //Uneven height
7044 {
7045 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
7046 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
7047 }
7048 3535 try_x += (offgrid ? 8 : 16);
7049 3535 }
7050
2/2
✓ Branch 0 taken 3535 times.
✓ Branch 1 taken 49 times.
3584 if(!ok) break;
7051
1/2
✓ Branch 0 taken 3535 times.
✗ Branch 1 not taken.
3535 if((usewid%16)>0) //Uneven width
7052 {
7053 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7054 try_y = 0;
7055 for ( ; tries_y > 0; --tries_y )
7056 {
7057 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
7058 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
7059 try_y += (offgrid ? 8 : 16);
7060 if (!ok) break;
7061 }
7062 if (!ok) break;
7063 if((usehei%16)>0) //Uneven height
7064 {
7065 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
7066 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
7067 }
7068 }
7069 3535 break;
7070 }
7071 case 15:
7072 case l_up:
7073 {
7074 2177 dx = dx1-s;
7075 2177 dy = dy1-s;
7076 2177 int32_t tries_x = usewid/(offgrid ? 8 : 16);
7077 2177 sv = ((isSideViewGravity())?7:0);
7078
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 2177 times.
4293 for ( ; tries_x > 0; --tries_x )
7079 {
7080 2177 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7081 2177 try_y = 0;
7082
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 2177 times.
4293 for ( ; tries_y > 0; --tries_y )
7083 {
7084
4/4
✓ Branch 0 taken 2132 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 2124 times.
✓ Branch 3 taken 8 times.
4301 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+try_x, y+useyoffs+try_y, kb) &&
7085
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2117 times.
2124 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+try_y, special,kb);
7086 2177 try_y += (offgrid ? 8 : 16);
7087
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 61 times.
2177 if (!ok) break;
7088 2116 }
7089
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 61 times.
2177 if (!ok) break;
7090
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2116 times.
2116 if((usehei%16)>0) //Uneven height
7091 {
7092 ok = !m_walkflag(x+usexoffs+try_x,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+try_x,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+try_x, y+useyoffs+usehei-1, kb) &&
7093 !flyerblocked(x+usexoffs+try_x,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+try_x,y+useyoffs+8+usehei-1, special,kb);
7094 }
7095 2116 try_x += (offgrid ? 8 : 16);
7096 2116 }
7097
2/2
✓ Branch 0 taken 2116 times.
✓ Branch 1 taken 61 times.
2177 if(!ok) break;
7098
1/2
✓ Branch 0 taken 2116 times.
✗ Branch 1 not taken.
2116 if((usewid%16)>0) //Uneven width
7099 {
7100 int32_t tries_y = usehei/(offgrid ? 8 : 16);
7101 try_y = 0;
7102 for ( ; tries_y > 0; --tries_y )
7103 {
7104 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+try_y,special,ndir, x+usexoffs+usewid-1, y+useyoffs+try_y, kb) &&
7105 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+try_y, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+try_y, special,kb);
7106 try_y += (offgrid ? 8 : 16);
7107 if (!ok) break;
7108 }
7109 if (!ok) break;
7110 if((usehei%16)>0) //Uneven height
7111 {
7112 ok = !m_walkflag(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) && !m_walkflag(x+usexoffs+dx+usewid-1,y+useyoffs+sv+usehei-1,special,ndir, x+usexoffs+usewid-1, y+useyoffs+usehei-1, kb) &&
7113 !flyerblocked(x+usexoffs+usewid-1,y+useyoffs+dy+usehei-1, special,kb) && !flyerblocked(x+usexoffs+dx+usewid-1,y+useyoffs+8+usehei-1, special,kb);
7114 }
7115 }
7116 2116 break;
7117 }
7118 default:
7119 db=99;
7120 return true;
7121 }
7122 //Z_eventlog("\n");
7123 36660 return ok;
7124 37069 }
7125
7126
7127 25186 bool enemy::canmove(int32_t ndir,zfix s,int32_t special, bool kb)
7128 {
7129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25186 times.
25186 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
7130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25186 times.
25186 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
7131
1/2
✓ Branch 0 taken 25186 times.
✗ Branch 1 not taken.
25186 if (usewid % 16 != 0) usewid += (16 - (usewid%16));
7132
1/2
✓ Branch 0 taken 25186 times.
✗ Branch 1 not taken.
25186 if (usehei % 16 != 0) usehei += (16 - (usehei%16));
7133 25186 --usewid;
7134 25186 --usehei;
7135 25186 return canmove(ndir,s,special,0,-8,usewid,usehei,kb);
7136 }
7137
7138 7611 bool enemy::canmove(int32_t ndir,int32_t special, bool kb)
7139 {
7140 7611 bool dodongo_move=true; //yes, it's an ugly hack, but we're going to rewrite everything later anyway - DN
7141
7142
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7608 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
7611 if(special==spw_clipright&&ndir==right)
7143 {
7144 dodongo_move=canmove(ndir,(zfix)1,special,0,-8,31,15,kb);
7145 }
7146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7611 times.
7611 int32_t usewid = (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ? hxsz : 16;
7147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7611 times.
7611 int32_t usehei = (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ? hysz : 16;
7148
1/2
✓ Branch 0 taken 7611 times.
✗ Branch 1 not taken.
7611 if (usewid % 16 != 0) usewid += (16 - (usewid%16));
7149
1/2
✓ Branch 0 taken 7611 times.
✗ Branch 1 not taken.
7611 if (usehei % 16 != 0) usehei += (16 - (usehei%16));
7150 7611 --usewid;
7151 7611 --usehei;
7152
2/2
✓ Branch 0 taken 3206 times.
✓ Branch 1 taken 4405 times.
7611 return canmove(ndir,(zfix)1,special,0,-8,usewid,usehei,kb)&&dodongo_move;
7153 }
7154
7155 186 bool enemy::canmove(int32_t ndir, bool kb)
7156 {
7157 186 return canmove(ndir,(zfix)1,spw_none,0,-8,15,15,kb);
7158 }
7159
7160 // 8-directional
7161 void enemy::newdir_8_old(int32_t newrate,int32_t newhoming,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
7162 {
7163 int32_t ndir=0;
7164
7165 // can move straight, check if it wants to turn
7166 if(canmove_old(dir,step,special,dx1,dy1,dx2,dy2))
7167 {
7168 if(grumble && (zc_oldrand()&4)<grumble) //Homing
7169 {
7170 int32_t w = Lwpns.idFirst(wBait);
7171
7172 if(w>=0)
7173 {
7174 int32_t bx = Lwpns.spr(w)->x;
7175 int32_t by = Lwpns.spr(w)->y;
7176
7177 ndir = (bx<x) ? left : (bx!=x) ? right : 0;
7178
7179 if(abs(int32_t(y)-by)>14)
7180 {
7181 if(ndir>0) // Already left or right
7182 {
7183 // Making the diagonal directions
7184 ndir += (by<y) ? 2 : 4;
7185 }
7186 else
7187 {
7188 ndir = (by<y) ? up : down;
7189 }
7190 }
7191
7192 if(canmove(ndir,special,false))
7193 {
7194 dir=ndir;
7195 return;
7196 }
7197 }
7198 }
7199
7200 // Homing added.
7201 if(newhoming && (zc_oldrand()&255)<newhoming)
7202 {
7203 ndir = lined_up(8,true);
7204
7205 if(ndir>=0 && canmove(ndir,special,false))
7206 {
7207 dir=ndir;
7208 }
7209
7210 return;
7211 }
7212
7213 int32_t r=zc_oldrand();
7214
7215 if(newrate>0 && !(r%newrate))
7216 {
7217 ndir = ((dir+((r&64)?-1:1))&7)+8;
7218 int32_t ndir2=((dir+((r&64)?1:-1))&7)+8;
7219
7220 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7221 dir=ndir;
7222 else if(canmove(ndir2,step,special,dx1,dy1,dx2,dy2,false))
7223 dir=ndir2;
7224
7225 if(dir==ndir && (newrate>=4)) // newrate>=4, otherwise movement is biased toward upper-left
7226 // due to numerous lost fractional components. -L
7227 {
7228 x.doFloor();
7229 y.doFloor();
7230 }
7231 }
7232
7233 return;
7234 }
7235
7236 // can't move straight, must turn
7237 int32_t i=0;
7238
7239 for(; i<32; i++) // Try random dir
7240 {
7241 ndir=(zc_oldrand()&7)+8;
7242
7243 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7244 break;
7245 }
7246
7247 if(i==32)
7248 {
7249 for(ndir=8; ndir<16; ndir++)
7250 {
7251 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7252 goto ok;
7253 }
7254
7255 ndir = (isSideViewGravity()) ? (zc_oldrand()&1 ? left : right) : -1; // Sideview enemies get trapped if their dir becomes -1
7256 }
7257
7258 ok:
7259 dir=ndir;
7260 x.doFloor();
7261 y.doFloor();
7262 }
7263
7264 3154 void enemy::newdir_8(int32_t newrate,int32_t newhoming,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
7265 {
7266 3154 int32_t ndir=0;
7267
7268 // can move straight, check if it wants to turn
7269
2/2
✓ Branch 0 taken 3018 times.
✓ Branch 1 taken 136 times.
3154 if(canmove(dir,step,special,dx1,dy1,dx2,dy2,false))
7270 {
7271
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3018 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3018 if(grumble && (zc_oldrand()&4)<abs(grumble)) //Homing
7272 {
7273 int32_t i = Lwpns.idFirst(wBait);
7274 if(i >= 0) //idfirst returns -1 if it can't find any
7275 {
7276 weapon *w = (weapon*)Lwpns.spr(i);
7277 if (get_bit(quest_rules, qr_FIND_CLOSEST_BAIT))
7278 {
7279 int32_t currentrange;
7280 if (distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0) currentrange = distance(x, y, w->x, w->y);
7281 else currentrange = -1;
7282 int curid = i;
7283 ++i; //increment beforehand cause we just checked the first bait weapon and all others must be after it. ...otherwise it wouldn't be the first. -Deedee
7284 for(; i<Lwpns.Count(); ++i)
7285 {
7286 weapon *lw = (weapon*)Lwpns.spr(i);
7287 if (lw->id == wBait && distance(x, y, lw->x, lw->y) < currentrange && (distance(x, y, lw->x, lw->y) < lw->misc2 || lw->misc2 == 0))
7288 {
7289 currentrange = distance(x, y, lw->x, lw->y);
7290 curid = i;
7291 }
7292 }
7293 i = curid;
7294 if (currentrange == -1) i = -1;
7295 }
7296 else
7297 {
7298 if (!(distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0)) i = -1;
7299 }
7300 if(i>=0)
7301 {
7302 int32_t bx = Lwpns.spr(i)->x;
7303 int32_t by = Lwpns.spr(i)->y;
7304
7305 ndir = (bx<x) ? left : (bx!=x) ? right : 0;
7306
7307 if(abs(int32_t(y)-by)>14)
7308 {
7309 if(ndir>0) // Already left or right
7310 {
7311 // Making the diagonal directions
7312 ndir += (by<y) ? 2 : 4;
7313 }
7314 else
7315 {
7316 ndir = (by<y) ? up : down;
7317 }
7318 }
7319 if (grumble < 0 || (itemsbuf[((weapon*)Lwpns.spr(i))->parentitem].flags & ITEM_FLAG1)) ndir = oppositeDir[ndir];
7320 if(canmove(ndir,special,false))
7321 {
7322 dir=ndir;
7323 return;
7324 }
7325 }
7326 }
7327 }
7328
7329 // Homing added.
7330
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3018 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3018 if(newhoming && (zc_oldrand()&255)<abs(newhoming))
7331 {
7332 ndir = lined_up(8,true);
7333 if (newhoming < 0 && ndir >= 0) ndir = oppositeDir[ndir];
7334 if(ndir>=0 && canmove(ndir,special,false))
7335 {
7336 dir=ndir;
7337 }
7338
7339 return;
7340 }
7341
7342 3018 int32_t r=zc_oldrand();
7343
7344
4/4
✓ Branch 0 taken 1438 times.
✓ Branch 1 taken 1580 times.
✓ Branch 2 taken 776 times.
✓ Branch 3 taken 662 times.
3018 if(newrate>0 && !(r%newrate))
7345 {
7346 662 ndir = ((dir+((r&64)?-1:1))&7)+8;
7347 662 int32_t ndir2=((dir+((r&64)?1:-1))&7)+8;
7348
7349
2/2
✓ Branch 0 taken 652 times.
✓ Branch 1 taken 10 times.
662 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7350 652 dir=ndir;
7351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 else if(canmove(ndir2,step,special,dx1,dy1,dx2,dy2,false))
7352 10 dir=ndir2;
7353
7354
3/4
✓ Branch 0 taken 652 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 652 times.
✗ Branch 3 not taken.
662 if(dir==ndir && (newrate>=4)) // newrate>=4, otherwise movement is biased toward upper-left
7355 // due to numerous lost fractional components. -L
7356 {
7357 x.doFloor();
7358 y.doFloor();
7359 }
7360 662 }
7361
7362 3018 return;
7363 }
7364
7365 // can't move straight, must turn
7366 136 int32_t i=0;
7367
7368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 260 times.
260 for(; i<32; i++) // Try random dir
7369 {
7370 260 ndir=(zc_oldrand()&7)+8;
7371
7372
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 136 times.
260 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7373 136 break;
7374 124 }
7375
7376
1/2
✓ Branch 0 taken 136 times.
✗ Branch 1 not taken.
136 if(i==32)
7377 {
7378 for(ndir=8; ndir<16; ndir++)
7379 {
7380 if(canmove(ndir,step,special,dx1,dy1,dx2,dy2,false))
7381 goto ok;
7382 }
7383
7384 ndir = (isSideViewGravity()) ? (zc_oldrand()&1 ? left : right) : -1; // Sideview enemies get trapped if their dir becomes -1
7385 }
7386
7387 ok:
7388 136 dir=ndir;
7389 136 x.doFloor();
7390 136 y.doFloor();
7391 3154 }
7392
7393 3154 void enemy::newdir_8(int32_t newrate,int32_t newhoming,int32_t special)
7394 {
7395 3154 newdir_8(newrate,newhoming,special,0,-8,15,15);
7396 3154 }
7397
7398 void enemy::newdir_8_old(int32_t newrate,int32_t newhoming,int32_t special)
7399 {
7400 newdir_8_old(newrate,newhoming,special,0,-8,15,15);
7401 }
7402
7403 // makes the enemy slide backwards when hit
7404 // sclk: first byte is clk, second byte is dir
7405 // makes the enemy slide backwards when hit
7406 // sclk: first byte is clk, second byte is dir
7407 128049 int32_t enemy::slide()
7408 {
7409
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128049 times.
128049 if(script_knockback_clk!=0) //scripted knockback
7410 {
7411 sclk = 0;
7412 return 1; //scripted knockback ran
7413 }
7414
5/6
✓ Branch 0 taken 722 times.
✓ Branch 1 taken 127327 times.
✓ Branch 2 taken 105 times.
✓ Branch 3 taken 617 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 105 times.
128049 if(sclk==0 || (hp<=0 && !immortal))
7415 127432 return 0;
7416
7417
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 617 times.
617 if(knockbackflags & FLAG_NOSLIDE)
7418 {
7419 sclk = 0;
7420 if(!OFFGRID_ENEMY)
7421 {
7422 //Fix to grid
7423 //x = (int32_t(x)+8)-((int32_t(x)+8)%16);
7424 //y = (int32_t(y)+8)-((int32_t(y)+8)%16);
7425 do_fix(x, 16, true);
7426 do_fix(y, 16, true);
7427 }
7428 return 0;
7429 }
7430
5/10
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 548 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 69 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 50 times.
✓ Branch 7 taken 19 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
617 if((sclk&255)==16 && (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION) || knockbackSpeed!=4 ? !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : 12),0,true) : !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : knockbackSpeed),0,0,0,15,15,true)))
7431 {
7432 19 sclk=0;
7433 19 return 0;
7434 }
7435
7436 598 --sclk;
7437
7438
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 249 times.
✓ Branch 4 taken 279 times.
598 switch(sclk>>8)
7439 {
7440 case up:
7441 {
7442
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
49 if(y<=(dmisc2==e2tSPLITHIT ? 0 : (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION)?16:0))) //vires
7443 {
7444 sclk=0;
7445 return 0;
7446 }
7447
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
49 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; } //vires
7448
7449 49 break;
7450 }
7451 case down:
7452 {
7453
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if(y>=(dmisc2==e2tSPLITHIT ? 150 : 160)) //was 160 --changed for vires bug.
7454 {
7455 sclk=0;
7456 return 0;
7457 }
7458
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
21 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; } //vires
7459
7460 21 break;
7461 }
7462 case left:
7463 {
7464
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 249 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 249 times.
249 if(x<=(dmisc2==e2tSPLITHIT ? 0 : (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION)?16:0)))
7465 {
7466 sclk=0;
7467 return 0;
7468 }
7469
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 249 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
249 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; }
7470
7471 249 break;
7472 }
7473 case right:
7474 {
7475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
279 if(x>=(dmisc2==e2tSPLITHIT ? 255 : 240)) //vires
7476 {
7477 sclk=0;
7478 return 0;
7479 }
7480
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 279 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
279 if ( dmisc2==e2tSPLITHIT && !canmove(sclk>>8,(zfix)(4),0,true) ) { sclk=0; return 0; } //vires
7481 279 break;
7482 }
7483 }
7484
7485 598 int32_t move = knockbackSpeed;
7486
2/2
✓ Branch 0 taken 567 times.
✓ Branch 1 taken 598 times.
1165 while(move>0)
7487 {
7488
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 598 times.
598 int32_t thismove = zc_min(8, move);
7489 598 move -= thismove;
7490 598 hitdir = (sclk>>8);
7491
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 249 times.
✓ Branch 4 taken 279 times.
598 switch(sclk>>8)
7492 {
7493 case up:
7494 49 y-=thismove;
7495 49 break;
7496
7497 case down:
7498 21 y+=thismove;
7499 21 break;
7500
7501 case left:
7502 249 x-=thismove;
7503 249 break;
7504
7505 case right:
7506 279 x+=thismove;
7507 279 break;
7508 }
7509
2/2
✓ Branch 0 taken 567 times.
✓ Branch 1 taken 31 times.
598 if(!canmove(sclk>>8,(zfix)0,0,true))
7510 {
7511
2/3
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
31 switch(sclk>>8)
7512 {
7513 case up:
7514 case down:
7515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if(y < 0)
7516 y = 0;
7517
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 else if((int32_t(y)&15) > 7)
7518 3 y=(int32_t(y)&0xF0)+16;
7519 else
7520 5 y=(int32_t(y)&0xF0);
7521
7522 8 break;
7523
7524 case left:
7525 case right:
7526
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 if(x < 0)
7527 x = 0;
7528
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 16 times.
23 else if((int32_t(x)&15) > 7)
7529 7 x=(int32_t(x)&0xF0)+16;
7530 else
7531 16 x=(int32_t(x)&0xF0);
7532
7533 23 break;
7534 }
7535
7536 31 sclk=0;
7537 31 clk3=0;
7538 31 break;
7539 }
7540 }
7541
7542
2/2
✓ Branch 0 taken 549 times.
✓ Branch 1 taken 49 times.
598 if((sclk&255)==0)
7543 {
7544 //hitdir = -1;
7545 49 sclk=0;
7546 49 }
7547 598 return 2;
7548 128049 }
7549
7550 bool enemy::can_slide()
7551 {
7552 if(sclk==0 || (hp<=0 && !immortal))
7553 return false;
7554
7555 if((sclk&255)==16 && (get_bit(quest_rules,qr_OLD_ENEMY_KNOCKBACK_COLLISION) || knockbackSpeed!=4 ? !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : 12),0,true) : !canmove(sclk>>8,(zfix) (dmisc2==e2tSPLITHIT ? 1 : knockbackSpeed),0,true)))
7556 {
7557 return false;
7558 }
7559
7560 return true;
7561 }
7562
7563 bool enemy::fslide()
7564 {
7565 if(sclk==0 || (hp<=0 && !immortal))
7566 return false;
7567
7568 if((sclk&255)==16 && !canmove(sclk>>8,(zfix)12,spw_floater,true))
7569 {
7570 sclk=0;
7571 return false;
7572 }
7573
7574 --sclk;
7575
7576 switch(sclk>>8)
7577 {
7578 case up:
7579 if(y<=16)
7580 {
7581 sclk=0;
7582 return false;
7583 }
7584
7585 break;
7586
7587 case down:
7588 if(y>=160)
7589 {
7590 sclk=0;
7591 return false;
7592 }
7593
7594 break;
7595
7596 case left:
7597 if(x<=16)
7598 {
7599 sclk=0;
7600 return false;
7601 }
7602
7603 break;
7604
7605 case right:
7606 if(x>=240)
7607 {
7608 sclk=0;
7609 return false;
7610 }
7611
7612 break;
7613 }
7614 hitdir = (sclk>>8);
7615 switch(sclk>>8)
7616 {
7617 case up:
7618 y-=4;
7619 break;
7620
7621 case down:
7622 y+=4;
7623 break;
7624
7625 case left:
7626 x-=4;
7627 break;
7628
7629 case right:
7630 x+=4;
7631 break;
7632 }
7633
7634 if(!canmove(sclk>>8,(zfix)0,spw_floater,true))
7635 {
7636 switch(sclk>>8)
7637 {
7638 case up:
7639 case down:
7640 if((int32_t(y)&15) > 7)
7641 y=(int32_t(y)&0xF0)+16;
7642 else
7643 y=(int32_t(y)&0xF0);
7644
7645 break;
7646
7647 case left:
7648 case right:
7649 if((int32_t(x)&15) > 7)
7650 x=(int32_t(x)&0xF0)+16;
7651 else
7652 x=(int32_t(x)&0xF0);
7653
7654 break;
7655 }
7656
7657 sclk=0;
7658 clk3=0;
7659 }
7660
7661 if((sclk&255)==0)
7662 sclk=0;
7663
7664 return true;
7665 }
7666
7667 bool enemy::knockback(int32_t time, int32_t dir, int32_t speed)
7668 {
7669 if((hp<=0 && !immortal)) return false; //No knocking back dead/mid-knockback enemies
7670 if(!canmove(dir,(zfix)speed,0,0,0,15,15,true)) return false; //from slide(); collision check
7671 bool ret = sprite::knockback(time, dir, speed);
7672 if(ret) sclk = 0; //kill engine knockback if interrupted
7673 //! Perhaps also set hitdir here, if needed for timing? -Z
7674 return ret;
7675 }
7676
7677 192390 bool enemy::runKnockback()
7678 {
7679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 192390 times.
192390 if((script_knockback_clk&0xFF)==0)
7680 {
7681 192390 script_knockback_clk = 0;
7682 192390 return false;
7683 }
7684 if(knockbackflags & FLAG_NOSCRIPTKNOCKBACK)
7685 {
7686 return false;
7687 }
7688 int32_t move = script_knockback_speed;
7689 int32_t kb_dir = script_knockback_clk>>8;
7690 --script_knockback_clk;
7691
7692 while(move>0)
7693 {
7694 int32_t thismove = zc_min(get_bit(quest_rules, qr_OLD_SCRIPTED_KNOCKBACK)?8:4, move);
7695 move -= thismove;
7696 hitdir = kb_dir;
7697 switch(kb_dir)
7698 {
7699 case r_up:
7700 case l_up:
7701 case up:
7702 y-=thismove;
7703 break;
7704
7705 case r_down:
7706 case l_down:
7707 case down:
7708 y+=thismove;
7709 break;
7710 }
7711 switch(kb_dir)
7712 {
7713 case l_up:
7714 case l_down:
7715 case left:
7716 x-=thismove;
7717 break;
7718
7719 case r_up:
7720 case r_down:
7721 case right:
7722 x+=thismove;
7723 break;
7724 }
7725 if (get_bit(quest_rules, qr_OLD_SCRIPTED_KNOCKBACK))
7726 {
7727 if(!canmove(kb_dir,(zfix)0,0,true))
7728 {
7729 script_knockback_clk=0;
7730 clk3=0;
7731 //Fix to grid
7732 switch(kb_dir)
7733 {
7734 case up:
7735 case down:
7736 break;
7737 default:
7738 if(x < 0)
7739 x = 0;
7740 else if((int32_t(x)&15) > 7)
7741 x=(int32_t(x)&0xF0)+16;
7742 else
7743 x=(int32_t(x)&0xF0);
7744 break;
7745 }
7746 switch(kb_dir)
7747 {
7748 case left:
7749 case right:
7750 break;
7751 default:
7752 if(y < 0)
7753 y = 0;
7754 else if((int32_t(y)&15) > 7)
7755 y=(int32_t(y)&0xF0)+16;
7756 else
7757 y=(int32_t(y)&0xF0);
7758 break;
7759 }
7760 break;
7761 }
7762 }
7763 else
7764 {
7765 if(!scr_canplace(x,y,0,true))
7766 {
7767 script_knockback_clk=0;
7768 clk3=0;
7769 //Fix to grid
7770 if (OFFGRID_ENEMY)
7771 {
7772 switch(kb_dir)
7773 {
7774 case up:
7775 case down:
7776 break;
7777 default:
7778 if(x < 0)
7779 x = 0;
7780 else if((int32_t(x)&7) > 3)
7781 x=(int32_t(x)&0xF8)+8;
7782 else
7783 x=(int32_t(x)&0xF8);
7784 break;
7785 }
7786 switch(kb_dir)
7787 {
7788 case left:
7789 case right:
7790 break;
7791 default:
7792 if(y < 0)
7793 y = 0;
7794 else if((int32_t(y)&7) > 3)
7795 y=(int32_t(y)&0xF8)+8;
7796 else
7797 y=(int32_t(y)&0xF8);
7798 break;
7799 }
7800 }
7801 else
7802 {
7803 switch(kb_dir)
7804 {
7805 case up:
7806 case down:
7807 break;
7808 default:
7809 if(x < 0)
7810 x = 0;
7811 else if((int32_t(x)&15) > 7)
7812 x=(int32_t(x)&0xF0)+16;
7813 else
7814 x=(int32_t(x)&0xF0);
7815 break;
7816 }
7817 switch(kb_dir)
7818 {
7819 case left:
7820 case right:
7821 break;
7822 default:
7823 if(y < 0)
7824 y = 0;
7825 else if((int32_t(y)&15) > 7)
7826 y=(int32_t(y)&0xF0)+16;
7827 else
7828 y=(int32_t(y)&0xF0);
7829 break;
7830 }
7831 }
7832 break;
7833 }
7834
7835 }
7836 }
7837 return true;
7838 192390 }
7839 // changes enemy's direction, checking restrictions
7840 // rate: 0 = no random changes, 16 = always random change
7841 // homing: 0 = none, 256 = always
7842 // grumble 0 = none, 4 = strongest appetite
7843 4410 void enemy::newdir(int32_t newrate,int32_t newhoming,int32_t special)
7844 {
7845 4410 int32_t ndir=-1;
7846
7847
4/4
✓ Branch 0 taken 3274 times.
✓ Branch 1 taken 1136 times.
✓ Branch 2 taken 2187 times.
✓ Branch 3 taken 1087 times.
4410 if(grumble != 0 && (zc_oldrand()&3)<abs(grumble)) //yes, I know checking if grumble is equal to if grumble == 0, but the latter makes the intention more clear to less experienced coders who might join.
7848 {
7849 1087 int32_t i = Lwpns.idFirst(wBait);
7850
1/2
✓ Branch 0 taken 1087 times.
✗ Branch 1 not taken.
1087 if(i >= 0) //idfirst returns -1 if it can't find any
7851 {
7852 weapon *w = (weapon*)Lwpns.spr(i);
7853 if (get_bit(quest_rules, qr_FIND_CLOSEST_BAIT))
7854 {
7855 int32_t currentrange;
7856 if (distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0) currentrange = distance(x, y, w->x, w->y);
7857 else currentrange = -1;
7858 int curid = i;
7859 ++i; //increment beforehand cause we just checked the first bait weapon and all others must be after it. ...otherwise it wouldn't be the first. -Deedee
7860 for(; i<Lwpns.Count(); ++i)
7861 {
7862 weapon *lw = (weapon*)Lwpns.spr(i);
7863 if (lw->id == wBait && distance(x, y, lw->x, lw->y) < currentrange && (distance(x, y, lw->x, lw->y) < lw->misc2 || lw->misc2 == 0))
7864 {
7865 currentrange = distance(x, y, lw->x, lw->y);
7866 curid = i;
7867 }
7868 }
7869 i = curid;
7870 if (currentrange == -1) i = -1;
7871 }
7872 else
7873 {
7874 if (!(distance(x, y, w->x, w->y) < w->misc2 || w->misc2 == 0)) i = -1;
7875 }
7876 if (i >= 0)
7877 {
7878 int32_t bx = Lwpns.spr(i)->x;
7879 int32_t by = Lwpns.spr(i)->y;
7880
7881 if(abs(int32_t(y)-by)>14)
7882 {
7883 ndir = (by<y) ? up : down;
7884 if (grumble < 0 || (itemsbuf[((weapon*)Lwpns.spr(i))->parentitem].flags & ITEM_FLAG1)) ndir = oppositeDir[ndir];
7885 if(canmove(ndir,special,false))
7886 {
7887 dir=ndir;
7888 return;
7889 }
7890 }
7891
7892 ndir = (bx<x) ? left : right;
7893 if (grumble < 0 || (itemsbuf[((weapon*)Lwpns.spr(i))->parentitem].flags & ITEM_FLAG1)) ndir = oppositeDir[ndir];
7894 if(canmove(ndir,special,false))
7895 {
7896 dir=ndir;
7897 return;
7898 }
7899 }
7900 }
7901 1087 }
7902
7903
2/2
✓ Branch 0 taken 2426 times.
✓ Branch 1 taken 1984 times.
4410 if((zc_oldrand()&255)<abs(newhoming))
7904 {
7905 1984 ndir = lined_up(8,false);
7906
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1984 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1984 if (newhoming < 0 && ndir >= 0) ndir = oppositeDir[ndir];
7907
4/4
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1468 times.
✓ Branch 2 taken 78 times.
✓ Branch 3 taken 438 times.
1984 if(ndir>=0 && canmove(ndir,special,false))
7908 {
7909 438 dir=ndir;
7910 438 return;
7911 }
7912 1546 }
7913
7914 3972 int32_t i=0;
7915
7916
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 7065 times.
7074 for(; i<32; i++)
7917 {
7918 7065 int32_t r=zc_oldrand();
7919
7920
2/2
✓ Branch 0 taken 2415 times.
✓ Branch 1 taken 4650 times.
7065 if((r&15)<newrate)
7921 2415 ndir=(r>>4)&3;
7922 else
7923 4650 ndir=dir;
7924
7925
2/2
✓ Branch 0 taken 3102 times.
✓ Branch 1 taken 3963 times.
7065 if(canmove(ndir,special,false))
7926 3963 break;
7927 3102 }
7928
7929
2/2
✓ Branch 0 taken 3963 times.
✓ Branch 1 taken 9 times.
3977 if(i==32)
7930 {
7931
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 5 times.
35 for(ndir=0; ndir<4; ndir++)
7932 {
7933
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 4 times.
30 if(canmove(ndir,special,false))
7934 4 goto ok;
7935 26 }
7936
7937
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 ndir = (isSideViewGravity()) ? (zc_oldrand()&1 ? left : right) : -1; // Sideview enemies get trapped if their dir becomes -1
7938 //...Isn't that the point? I'm not sure I understand. Certainly beats phasing through walls... -Dimi
7939 5 }
7940
7941 ok:
7942 3972 dir = ndir;
7943 4410 }
7944
7945 void enemy::newdir()
7946 {
7947 newdir(4,0,spw_none);
7948 }
7949
7950 zfix enemy::distance_left()
7951 {
7952 int32_t a2=x.getInt();
7953 int32_t b2=y.getInt();
7954
7955 switch(dir)
7956 {
7957 case up:
7958 return (zfix)(b2&0xF);
7959
7960 case down:
7961 return (zfix)(16-(b2&0xF));
7962
7963 case left:
7964 return (zfix)(a2&0xF);
7965
7966 case right:
7967 return (zfix)(16-(a2&0xF));
7968 }
7969
7970 return (zfix)0;
7971 }
7972
7973 // keeps walking around
7974 void enemy::constant_walk(int32_t newrate,int32_t newhoming,int32_t special)
7975 {
7976 if(slide())
7977 return;
7978
7979 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock )
7980 return;
7981
7982 if(clk3<=0)
7983 {
7984 fix_coords(true);
7985 newdir(newrate,newhoming,special);
7986
7987 if(step==0)
7988 clk3=0;
7989 else
7990 clk3=int32_t(16.0/step);
7991 }
7992 else if(scored)
7993 {
7994 dir^=1;
7995 if (step != 0) clk3=int32_t(16.0/step)-clk3;
7996 else clk3=32767;
7997 }
7998
7999 if (step != 0) --clk3;
8000 move(step);
8001 }
8002
8003 void enemy::constant_walk()
8004 {
8005 constant_walk(4,0,spw_none);
8006 }
8007
8008 int32_t enemy::pos(int32_t newx,int32_t newy)
8009 {
8010 return (newy<<8)+newx;
8011 }
8012
8013 // for variable step rates
8014 void enemy::variable_walk(int32_t newrate,int32_t newhoming,int32_t special)
8015 {
8016 if(slide())
8017 return;
8018
8019 if(clk<0 || dying || stunclk || watch || step == 0 || ceiling || frozenclock )
8020 return;
8021
8022 zfix dx = (zfix)0;
8023 zfix dy = (zfix)0;
8024
8025 switch(dir)
8026 {
8027 case 8:
8028 case up:
8029 dy-=step;
8030 break;
8031
8032 case 12:
8033 case down:
8034 dy+=step;
8035 break;
8036
8037 case 14:
8038 case left:
8039 dx-=step;
8040 break;
8041
8042 case 10:
8043 case right:
8044 dx+=step;
8045 break;
8046
8047 case 15:
8048 case l_up:
8049 dx-=step;
8050 dy-=step;
8051 break;
8052
8053 case 9:
8054 case r_up:
8055 dx+=step;
8056 dy-=step;
8057 break;
8058
8059 case 13:
8060 case l_down:
8061 dx-=step;
8062 dy+=step;
8063 break;
8064
8065 case 11:
8066 case r_down:
8067 dx+=step;
8068 dy+=step;
8069 break;
8070 }
8071
8072 if(((int32_t(x)&15)==0 && (int32_t(y)&15)==0 && clk3!=pos(x,y)) ||
8073 m_walkflag(int32_t(x+dx),int32_t(y+dy), spw_halfstep, dir))
8074 {
8075 fix_coords();
8076 newdir(newrate,newhoming,special);
8077 clk3=pos(x,y);
8078 }
8079
8080 move(step);
8081 }
8082
8083 // pauses for a while after it makes a complete move (to a new square)
8084 124509 void enemy::halting_walk(int32_t newrate,int32_t newhoming,int32_t special,int32_t newhrate, int32_t haltcnt)
8085 {
8086
4/4
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 123837 times.
✓ Branch 2 taken 490 times.
✓ Branch 3 taken 182 times.
124509 if(sclk && clk2)
8087 {
8088 182 clk3=0;
8089 182 }
8090
8091
9/14
✓ Branch 0 taken 123942 times.
✓ Branch 1 taken 567 times.
✓ Branch 2 taken 123942 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 123942 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 120691 times.
✓ Branch 7 taken 3251 times.
✓ Branch 8 taken 120691 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 120691 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 120691 times.
124509 if(slide() || clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8092 {
8093 3818 return;
8094 }
8095
8096
2/2
✓ Branch 0 taken 35481 times.
✓ Branch 1 taken 85210 times.
120691 if(clk2>0)
8097 {
8098 35481 --clk2;
8099 35481 return;
8100 }
8101
8102
2/2
✓ Branch 0 taken 4408 times.
✓ Branch 1 taken 80802 times.
85210 if(clk3<=0)
8103 {
8104 4408 fix_coords(true);
8105 4408 newdir(newrate,newhoming,special);
8106 4408 clk3=int32_t(16.0/step);
8107
1/2
✓ Branch 0 taken 4408 times.
✗ Branch 1 not taken.
4408 if (step == 0) clk3 = 32767; //It used to return this in 2.53 and I'm unsure why; I'm guessing dividing by 0 gave max int? Either way, can't be 0 here or scripts break.
8108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4408 times.
4408 if(clk2<0)
8109 {
8110 clk2=0;
8111 }
8112
2/2
✓ Branch 0 taken 862 times.
✓ Branch 1 taken 3546 times.
4408 else if((zc_oldrand()&15)<newhrate)
8113 {
8114 862 clk2=haltcnt;
8115 862 return;
8116 }
8117 3546 }
8118
2/2
✓ Branch 0 taken 80790 times.
✓ Branch 1 taken 12 times.
80802 else if(scored)
8119 {
8120 12 dir^=1;
8121
8122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (step != 0) clk3=int32_t(16.0/step)-clk3;
8123 else clk3=32767;
8124 12 }
8125
8126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84348 times.
84348 if (step != 0) --clk3;
8127 84348 move(step);
8128 124509 }
8129
8130 // 8-directional movement, aligns to 8 pixels
8131 void enemy::constant_walk_8(int32_t newrate,int32_t newhoming,int32_t special)
8132 {
8133 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8134 return;
8135
8136 if(clk3<=0)
8137 {
8138 newdir_8(newrate,newhoming,special);
8139 clk3=int32_t(8.0/step);
8140 if (step == 0) clk3 = 32767;
8141 }
8142
8143 if (step != 0) --clk3;
8144 move(step);
8145 }
8146 // 8-directional movement, aligns to 8 pixels
8147 void enemy::constant_walk_8_old(int32_t newrate,int32_t newhoming,int32_t special)
8148 {
8149 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8150 return;
8151
8152 if(clk3<=0)
8153 {
8154 newdir_8(newrate,newhoming,special);
8155 clk3=int32_t(8.0/step);
8156 if (step == 0) clk3 = 32767;
8157 }
8158
8159 if (step != 0) --clk3;
8160 move(step);
8161 }
8162
8163 void enemy::halting_walk_8(int32_t newrate,int32_t newhoming, int32_t newclk,int32_t special,int32_t newhrate, int32_t haltcnt)
8164 {
8165 if(clk<0 || dying || stunclk || watch || frozenclock)
8166 return;
8167
8168 if(!canmove(dir,step,special,false))
8169 clk3=0;
8170
8171 if(clk2>0)
8172 {
8173 --clk2;
8174 return;
8175 }
8176
8177 if(clk3<=0)
8178 {
8179 newdir_8(newrate,newhoming,special);
8180 clk3=newclk;
8181
8182 if(clk2<0)
8183 {
8184 clk2=0;
8185 }
8186 else if((zc_oldrand()&15)<newhrate)
8187 {
8188 newdir_8(newrate,newhoming,special);
8189 clk2=haltcnt;
8190 return;
8191 }
8192 }
8193
8194 --clk3;
8195 move(step);
8196 }
8197
8198 // 8-directional movement, no alignment
8199 26061 void enemy::variable_walk_8(int32_t newrate,int32_t newhoming, int32_t newclk,int32_t special)
8200 {
8201
7/12
✓ Branch 0 taken 24519 times.
✓ Branch 1 taken 1542 times.
✓ Branch 2 taken 24519 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24519 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24519 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 24519 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 24519 times.
26061 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8202 1542 return;
8203
8204
2/2
✓ Branch 0 taken 24383 times.
✓ Branch 1 taken 136 times.
24519 if(!canmove(dir,step,special,false))
8205 136 clk3=0;
8206
8207
2/2
✓ Branch 0 taken 21365 times.
✓ Branch 1 taken 3154 times.
24519 if(clk3<=0)
8208 {
8209 3154 newdir_8(newrate,newhoming,special);
8210 3154 clk3=newclk;
8211 3154 }
8212
8213 24519 --clk3;
8214 24519 move(step);
8215 26061 }
8216
8217 // same as above but with variable enemy size
8218 void enemy::variable_walk_8(int32_t newrate,int32_t newhoming, int32_t newclk,int32_t special,int32_t dx1,int32_t dy1,int32_t dx2,int32_t dy2)
8219 {
8220 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
8221 return;
8222
8223 if(!canmove(dir,step,special,dx1,dy1,dx2,dy2,false))
8224 clk3=0;
8225
8226 if(clk3<=0)
8227 {
8228 newdir_8(newrate,newhoming,special,dx1,dy1,dx2,dy2);
8229 clk3=newclk;
8230 }
8231
8232 --clk3;
8233 move(step);
8234 }
8235
8236 // the variable speed floater movement
8237 // ms is max speed
8238 // ss is step speed
8239 // s is step count
8240 // p is pause count
8241 // g is graduality :)
8242 //floater_walk(rate,hrate,dstep/100,(zfix)0,10,dmisc16,dmisc17);
8243 23060 void enemy::floater_walk(int32_t newrate,int32_t newclk,zfix ms,zfix ss,int32_t s,int32_t p, int32_t g)
8244 {
8245 23060 ++clk2;
8246 23060 byte over_pit = overpit(this);
8247
8248
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 23060 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
23060 if(dmisc1 && over_pit) p = 0;
8249
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 715 times.
✓ Branch 2 taken 12004 times.
✓ Branch 3 taken 8833 times.
✓ Branch 4 taken 1508 times.
23060 switch(movestatus)
8250 {
8251 //! This needs a case 4 (landing)....if we want to halt, we move to case 4, and
8252 //! if the conditions prevent it, we jump back to case 2.
8253 case 0: // paused
8254
2/2
✓ Branch 0 taken 711 times.
✓ Branch 1 taken 4 times.
715 if(clk2>=p)
8255 {
8256 4 movestatus=1;
8257 4 clk2=0;
8258 4 }
8259
8260 715 break;
8261
8262 case 1: // speeding up
8263
1/2
✓ Branch 0 taken 12004 times.
✗ Branch 1 not taken.
12004 if (s >= 0)
8264 {
8265
2/2
✓ Branch 0 taken 11948 times.
✓ Branch 1 taken 56 times.
12004 if(clk2<g*s)
8266 {
8267
2/2
✓ Branch 0 taken 11182 times.
✓ Branch 1 taken 766 times.
11948 if(!((clk2-1)%g))
8268 766 step+=ss;
8269 11948 }
8270 else
8271 {
8272 56 movestatus=2;
8273 56 clk2=0;
8274 }
8275 12004 }
8276 else
8277 {
8278 if(step < ms)
8279 {
8280 if(!((clk2-1)%g))
8281 {
8282 step+=ss;
8283 if (step >= ms) step = ms;
8284 }
8285 }
8286 else
8287 {
8288 step = ms;
8289 movestatus=2;
8290 clk2=0;
8291 }
8292 }
8293
8294 12004 break;
8295
8296 case 2: // normal
8297 8833 step=ms;
8298
8299
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 8833 times.
✓ Branch 2 taken 2136 times.
✓ Branch 3 taken 6697 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6697 times.
✓ Branch 6 taken 6685 times.
✓ Branch 7 taken 12 times.
8833 if(clk2>(dmisc15>0?dmisc15:48) && !(zc_oldrand()%(dmisc14>0?dmisc14:768)))
8300 {
8301
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (s >= 0) step=ss*s;
8302 else step=ms;
8303 12 movestatus=3;
8304 12 clk2=0;
8305 12 }
8306
8307 8833 break;
8308
8309 case 3: // slowing down
8310
1/2
✓ Branch 0 taken 1508 times.
✗ Branch 1 not taken.
1508 if (s >= 0)
8311 {
8312
2/2
✓ Branch 0 taken 1501 times.
✓ Branch 1 taken 7 times.
1508 if(clk2<=g*s)
8313 {
8314 { //don't slow down over pits
8315
8316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1501 times.
1501 if(over_pit)
8317 {
8318 if(dmisc1)
8319 {
8320 step=ms;
8321 }
8322 }
8323 else //can slow down
8324 {
8325
3/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 1410 times.
✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
1501 if(!(clk2%g) && !dmisc1)
8326 91 step-=ss;
8327 }
8328 }
8329
8330
8331 1501 }
8332 else
8333 {
8334 //if((moveflags&FLAG_CAN_PITFALL)) //don't check pits if the enemy ignores them
8335 //this doesn't help keese, as they have a z of 0.
8336 //they always nee to run this check.
8337 {
8338
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7 if(over_pit &&!dmisc1)
8339 {
8340 --clk2; //if over a pit, don't land, and revert clock change
8341 }
8342 else //can land safely
8343 {
8344 7 movestatus=0;
8345
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7 if(dmisc1&&!over_pit)
8346 step=0;
8347 7 clk2=0;
8348 }
8349 }
8350
8351 }
8352 1508 }
8353 else
8354 {
8355 if(step > 0)
8356 {
8357 if(over_pit)
8358 {
8359 if(dmisc1)
8360 {
8361 step=ms;
8362 }
8363 }
8364 else //can slow down
8365 {
8366 if(!(clk2%g))
8367 step-=ss;
8368 }
8369 }
8370 else
8371 {
8372 //if((moveflags&FLAG_CAN_PITFALL)) //don't check pits if the enemy ignores them
8373 //this doesn't help keese, as they have a z of 0.
8374 //they always nee to run this check.
8375 if(over_pit)
8376 {
8377 step+=ss; //if over a pit, don't land, and revert clock change
8378 }
8379 else //can land safely
8380 {
8381 movestatus=0;
8382 step=0;
8383 clk2=0;
8384 }
8385 }
8386 }
8387
8388 1508 break;
8389 }
8390
8391
2/2
✓ Branch 0 taken 8877 times.
✓ Branch 1 taken 14183 times.
23060 variable_walk_8(movestatus==2?newrate:0,homing,newclk,spw_floater);
8392 23060 }
8393
8394 void enemy::floater_walk(int32_t newrate,int32_t newclk,zfix s)
8395 {
8396 floater_walk(newrate,newclk,s,(zfix)0.125,3,80,32);
8397 }
8398
8399 // Checks if enemy is lined up with Hero. If so, returns direction Hero is
8400 // at as compared to enemy. Returns -1 if not lined up. Range is inclusive.
8401 1984 int32_t enemy::lined_up(int32_t range, bool dir8)
8402 {
8403 1984 int32_t lx = Hero.getX();
8404 1984 int32_t ly = Hero.getY();
8405
8406
2/2
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 1815 times.
1984 if(abs(lx-int32_t(x))<=range)
8407 {
8408
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 84 times.
169 if(ly<y)
8409 {
8410 85 return up;
8411 }
8412
8413 84 return down;
8414 }
8415
8416
2/2
✓ Branch 0 taken 347 times.
✓ Branch 1 taken 1468 times.
1815 if(abs(ly-int32_t(y))<=range)
8417 {
8418
2/2
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 163 times.
347 if(lx<x)
8419 {
8420 184 return left;
8421 }
8422
8423 163 return right;
8424 }
8425
8426
1/2
✓ Branch 0 taken 1468 times.
✗ Branch 1 not taken.
1468 if(dir8)
8427 {
8428 if(abs(lx-x)-abs(ly-y)<=range)
8429 //if(abs(lx-x)-abs(ly-y)<=range && abs(ly-y)-abs(lx-x)<=range) //Fix floating enemies not seeking hero. -Tamamo
8430 {
8431 if(ly<y)
8432 {
8433 if(lx<x)
8434 {
8435 return l_up;
8436 }
8437 else
8438 {
8439 return r_up;
8440 }
8441 }
8442 else
8443 {
8444 if(lx<x)
8445 {
8446 return l_down;
8447 }
8448 else
8449 {
8450 return r_down;
8451 }
8452 }
8453 }
8454 }
8455
8456 1468 return -1;
8457 1984 }
8458
8459 // returns true if Hero is within 'range' pixels of the enemy
8460 3 bool enemy::HeroInRange(int32_t range)
8461 {
8462 3 int32_t lx = Hero.getX();
8463 3 int32_t ly = Hero.getY();
8464
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 return abs(lx-int32_t(x))<=range && abs(ly-int32_t(y))<=range;
8465 }
8466
8467 // place the enemy in line with Hero (red wizzrobes)
8468 void enemy::place_on_axis(bool floater, bool solid_ok)
8469 {
8470 int32_t lx=zc_min(zc_max(int32_t(Hero.getX())&0xF0,32),208);
8471 int32_t ly=zc_min(zc_max(int32_t(Hero.getY())&0xF0,32),128);
8472 int32_t pos2=zc_oldrand()%23;
8473 int32_t tried=0;
8474 bool last_resort,placed=false;
8475
8476
8477 do
8478 {
8479 if(pos2<14)
8480 {
8481 x=(pos2<<4)+16;
8482 y=ly;
8483 }
8484 else
8485 {
8486 x=lx;
8487 y=((pos2-14)<<4)+16;
8488 }
8489
8490 // Don't commit to a last resort if position is out of bounds.
8491 last_resort= !(x<32 || y<32 || x>=224 || y>=144);
8492
8493 if(abs(lx-int32_t(x))>16 || abs(ly-int32_t(y))>16)
8494 {
8495 // Red Wizzrobes should be able to appear on water, but not other
8496 // solid combos; however, they could appear on solid combos in 2.10,
8497 // and some quests depend on that.
8498 if((solid_ok || !m_walkflag(x,y,floater ? spw_water : spw_door, dir))
8499 && !flyerblocked(x,y,floater ? spw_floater : spw_door))
8500 placed=true;
8501 }
8502
8503 if(!placed && tried>=22 && last_resort)
8504 {
8505 placed=true;
8506 }
8507
8508 ++tried;
8509 pos2=(pos2+3)%23;
8510 }
8511 while(!placed);
8512
8513 if(y==ly)
8514 dir=(x<lx)?right:left;
8515 else
8516 dir=(y<ly)?down:up;
8517
8518 clk2=tried;
8519 }
8520
8521 143132 int32_t enemy::n_frame_n_dir(int32_t frames, int32_t ndir, int32_t f4)
8522 {
8523 143132 int32_t t = o_tile;
8524 143132 int32_t b = o_tile;
8525
8526 // Darknuts, but also Wizzrobes and Wallmasters
8527
2/4
✓ Branch 0 taken 39193 times.
✓ Branch 1 taken 103939 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
143132 switch(family)
8528 {
8529 case eeWALK:
8530
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 103939 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
103939 if(dmisc9==e9tPOLSVOICE && clk2>=0 && do_animation)
8531 {
8532 tile=s_tile;
8533 t=s_tile;
8534 b=s_tile;
8535 }
8536
8537 103939 break;
8538
8539 case eeTRAP:
8540 if(dummy_int[1] && guysbuf[id].flags2 & eneflag_trp2 && do_animation) // Just to make sure
8541 {
8542 tile=s_tile;
8543 t=s_tile;
8544 b=s_tile;
8545 }
8546
8547 break;
8548
8549 case eeSPINTILE:
8550 if(misc>=96 && do_animation)
8551 {
8552 tile=o_tile+frames*ndir;
8553 t=tile;
8554 }
8555
8556 break;
8557 }
8558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 143132 times.
143132 if ( do_animation )
8559 {
8560
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 143132 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 143132 times.
143132 if(ndir!=0) switch(frames)
8561 {
8562 case 2:
8563 tiledir_small(dir,ndir==4);
8564 break;
8565
8566 case 3:
8567 tiledir_three(dir);
8568 break;
8569
8570 case 4:
8571 143132 tiledir(dir,ndir==4);
8572 143132 break;
8573 143132 }
8574
8575
2/2
✓ Branch 0 taken 103939 times.
✓ Branch 1 taken 39193 times.
143132 if(family==eeWALK)
8576
6/6
✓ Branch 0 taken 86057 times.
✓ Branch 1 taken 17882 times.
✓ Branch 2 taken 77595 times.
✓ Branch 3 taken 26344 times.
✓ Branch 4 taken 21744 times.
✓ Branch 5 taken 4600 times.
103939 tile=zc_min(tile+f4, t+frames*(zc_max(dir, 0)+1)-1);
8577 else
8578 39193 tile+=f4;
8579 143132 }
8580 143132 return b;
8581 }
8582
8583 void enemy::tiledir_three(int32_t ndir)
8584 {
8585 if ( !do_animation ) return;
8586 flip=0;
8587
8588 switch(ndir)
8589 {
8590 case right:
8591 tile+=3;
8592 [[fallthrough]];
8593
8594 case left:
8595 tile+=3;
8596 [[fallthrough]];
8597
8598 case down:
8599 tile+=3;
8600 [[fallthrough]];
8601
8602 case up:
8603 break;
8604 }
8605 }
8606
8607 void enemy::tiledir_small(int32_t ndir, bool fourdir)
8608 {
8609 if ( !do_animation ) return;
8610 flip=0;
8611
8612 switch(ndir)
8613 {
8614 case 8:
8615 case up:
8616 break;
8617
8618 case 12:
8619 case down:
8620 tile+=2;
8621 break;
8622
8623 case 14:
8624 case left:
8625 tile+=4;
8626 break;
8627
8628 case 10:
8629 case right:
8630 tile+=6;
8631 break;
8632
8633 case 9:
8634 case r_up:
8635 if(fourdir)
8636 break;
8637
8638 tile+=10;
8639 break;
8640
8641 case 11:
8642 case r_down:
8643 if(fourdir)
8644 tile+=2;
8645 else
8646 tile+=14;
8647
8648 break;
8649
8650 case 13:
8651 case l_down:
8652 if(fourdir)
8653 tile+=2;
8654 else
8655 tile+=12;
8656
8657 break;
8658
8659 case 15:
8660 case l_up:
8661 if(fourdir)
8662 break;
8663
8664 tile+=8;
8665 break;
8666
8667 default:
8668 //dir=(zc_oldrand()*100)%8;
8669 //tiledir_small(dir);
8670 // flip=zc_oldrand()&3;
8671 // tile=(zc_oldrand()*100000)%NEWMAXTILES;
8672 break;
8673 }
8674 }
8675
8676 149821 void enemy::tiledir(int32_t ndir, bool fourdir)
8677 {
8678
1/2
✓ Branch 0 taken 149821 times.
✗ Branch 1 not taken.
149821 if ( !do_animation ) return;
8679 149821 flip=0;
8680
8681
8/9
✓ Branch 0 taken 26780 times.
✓ Branch 1 taken 22383 times.
✓ Branch 2 taken 39766 times.
✓ Branch 3 taken 40614 times.
✓ Branch 4 taken 5350 times.
✓ Branch 5 taken 6896 times.
✓ Branch 6 taken 5206 times.
✓ Branch 7 taken 2826 times.
✗ Branch 8 not taken.
149821 switch(ndir)
8682 {
8683 case 8:
8684 case up:
8685 26780 break;
8686
8687 case 12:
8688 case down:
8689 22383 tile+=4;
8690 22383 break;
8691
8692 case 14:
8693 case left:
8694 39766 tile+=8;
8695 39766 break;
8696
8697 case 10:
8698 case right:
8699 40614 tile+=12;
8700 40614 break;
8701
8702 case 9:
8703 case r_up:
8704
2/2
✓ Branch 0 taken 535 times.
✓ Branch 1 taken 4815 times.
5350 if(fourdir)
8705 535 break;
8706 else
8707 4815 tile+=24;
8708
8709 4815 break;
8710
8711 case 11:
8712 case r_down:
8713
2/2
✓ Branch 0 taken 870 times.
✓ Branch 1 taken 6026 times.
6896 if(fourdir)
8714 870 tile+=4;
8715 else
8716 6026 tile+=32;
8717
8718 6896 break;
8719
8720 case 13:
8721 case l_down:
8722
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 5100 times.
5206 if(fourdir)
8723 106 tile+=4;
8724 else
8725 5100 tile+=28;
8726
8727 5206 break;
8728
8729 case 15:
8730 case l_up:
8731
2/2
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 2758 times.
2826 if(fourdir)
8732 68 break;
8733 else
8734 2758 tile+=20;
8735
8736 2758 break;
8737
8738 default:
8739 //dir=(zc_oldrand()*100)%8;
8740 //tiledir(dir);
8741 // flip=zc_oldrand()&3;
8742 // tile=(zc_oldrand()*100000)%NEWMAXTILES;
8743 break;
8744 }
8745 149821 }
8746
8747 void enemy::tiledir_big(int32_t ndir, bool fourdir)
8748 {
8749 if ( !do_animation ) return;
8750 flip=0;
8751
8752 switch(ndir)
8753 {
8754 case 8:
8755 case up:
8756 break;
8757
8758 case 12:
8759 case down:
8760 tile+=8;
8761 break;
8762
8763 case 14:
8764 case left:
8765 tile+=40;
8766 break;
8767
8768 case 10:
8769 case right:
8770 tile+=48;
8771 break;
8772
8773 case 9:
8774 case r_up:
8775 if(fourdir)
8776 break;
8777
8778 tile+=88;
8779 break;
8780
8781 case 11:
8782 case r_down:
8783 if(fourdir)
8784 tile+=8;
8785 else
8786 tile+=128;
8787
8788 break;
8789
8790 case 13:
8791 case l_down:
8792 if(fourdir)
8793 tile+=8;
8794 else
8795 tile+=120;
8796
8797 break;
8798
8799 case 15:
8800 case l_up:
8801 if(fourdir)
8802 break;
8803
8804 tile+=80;
8805 break;
8806
8807 default:
8808 //dir=(zc_oldrand()*100)%8;
8809 //tiledir_big(dir);
8810 // flip=zc_oldrand()&3;
8811 // tile=(zc_oldrand()*100000)%NEWMAXTILES;
8812 break;
8813 }
8814 }
8815
8816 230566 void enemy::update_enemy_frame()
8817 {
8818
2/4
✓ Branch 0 taken 230566 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 230566 times.
230566 if(fallclk||drownclk) return;
8819
1/2
✓ Branch 0 taken 230566 times.
✗ Branch 1 not taken.
230566 if (!do_animation)
8820 return;
8821
8822
3/4
✓ Branch 0 taken 62970 times.
✓ Branch 1 taken 167596 times.
✓ Branch 2 taken 62970 times.
✗ Branch 3 not taken.
230566 if (get_bit(quest_rules,qr_OLD_TILE_INITIALIZATION) || tile == 0) tile = o_tile; //tile was initialized here before. It needs to be initialized here as well.
8823
8824
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
230566 if(get_bit(quest_rules,qr_ANONE_NOANIM)
8825
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 230566 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
230566 && anim == aNONE && family != eeGUY)
8826 return;
8827
2/2
✓ Branch 0 taken 229465 times.
✓ Branch 1 taken 1101 times.
230566 int32_t newfrate = zc_max(frate,4);
8828 230566 int32_t f4=abs(clk/(newfrate/4)); // casts clk to [0,1,2,3]
8829 230566 int32_t f2=abs(clk/(newfrate/2)); // casts clk to [0,1]
8830
2/2
✓ Branch 0 taken 161073 times.
✓ Branch 1 taken 69493 times.
230566 int32_t fx = get_bit(quest_rules, qr_NEWENEMYTILES) ? f4 : f2;
8831 230566 tile = o_tile;
8832 230566 int32_t basetile = o_tile;
8833 230566 int32_t tilerows = 1; // How many rows of tiles? The Extend code needs to know.
8834 230566 bool ignore_extend = false;
8835
17/40
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16798 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 4548 times.
✓ Branch 7 taken 3737 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 5255 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1053 times.
✓ Branch 21 taken 2952 times.
✓ Branch 22 taken 16892 times.
✓ Branch 23 taken 3515 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 91888 times.
✓ Branch 27 taken 12051 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 9702 times.
✓ Branch 30 taken 9236 times.
✓ Branch 31 taken 884 times.
✓ Branch 32 taken 2677 times.
✓ Branch 33 taken 9464 times.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 36 taken 39193 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 721 times.
✗ Branch 39 not taken.
230566 switch(anim)
8836 {
8837
8838 case aDONGO:
8839 {
8840 int32_t fr = stunclk>0 ? 16 : 8;
8841
8842 if(!dying && clk2>0 && clk2<=64)
8843 {
8844 // bloated
8845 switch(dir)
8846 {
8847 case up:
8848 tile+=9;
8849 flip=0;
8850 xofs=0;
8851 dummy_int[1]=0; //no additional tiles
8852 break;
8853
8854 case down:
8855 tile+=7;
8856 flip=0;
8857 xofs=0;
8858 dummy_int[1]=0; //no additional tiles
8859 break;
8860
8861 case left:
8862 flip=1;
8863 tile+=4;
8864 xofs=16;
8865 dummy_int[1]=1; //second tile is next tile
8866 break;
8867
8868 case right:
8869 flip=0;
8870 tile+=5;
8871 xofs=16;
8872 dummy_int[1]=-1; //second tile is previous tile
8873 break;
8874 }
8875 }
8876 else if(!dying || clk2>19)
8877 {
8878 // normal
8879 switch(dir)
8880 {
8881 case up:
8882 tile+=8;
8883 flip=(clk&fr)?1:0;
8884 xofs=0;
8885 dummy_int[1]=0; //no additional tiles
8886 break;
8887
8888 case down:
8889 tile+=6;
8890 flip=(clk&fr)?1:0;
8891 xofs=0;
8892 dummy_int[1]=0; //no additional tiles
8893 break;
8894
8895 case left:
8896 flip=1;
8897 tile+=(clk&fr)?2:0;
8898 xofs=16;
8899 dummy_int[1]=1; //second tile is next tile
8900 break;
8901
8902 case right:
8903 flip=0;
8904 tile+=(clk&fr)?3:1;
8905 xofs=16;
8906 dummy_int[1]=-1; //second tile is next tile
8907 break;
8908 }
8909 }
8910 }
8911 break;
8912
8913 case aNEWDONGO:
8914 {
8915 int32_t fr4=0;
8916
8917 if(!dying && clk2>0 && clk2<=64)
8918 {
8919 // bloated
8920 if(clk2>=0)
8921 {
8922 fr4=3;
8923 }
8924
8925 if(clk2>=16)
8926 {
8927 fr4=2;
8928 }
8929
8930 if(clk2>=32)
8931 {
8932 fr4=1;
8933 }
8934
8935 if(clk2>=48)
8936 {
8937 fr4=0;
8938 }
8939
8940 switch(dir)
8941 {
8942 case up:
8943 xofs=0;
8944 tile+=8+fr4;
8945 dummy_int[1]=0; //no additional tiles
8946 break;
8947
8948 case down:
8949 xofs=0;
8950 tile+=12+fr4;
8951 dummy_int[1]=0; //no additional tiles
8952 break;
8953
8954 case left:
8955 tile+=29+(2*fr4);
8956 xofs=16;
8957 dummy_int[1]=-1; //second tile is previous tile
8958 break;
8959
8960 case right:
8961 tile+=49+(2*fr4);
8962 xofs=16;
8963 dummy_int[1]=-1; //second tile is previous tile
8964 break;
8965 }
8966 }
8967 else if(!dying || clk2>19)
8968 {
8969 // normal
8970 switch(dir)
8971 {
8972 case up:
8973 xofs=0;
8974 tile+=((clk&12)>>2);
8975 dummy_int[1]=0; //no additional tiles
8976 break;
8977
8978 case down:
8979 xofs=0;
8980 tile+=4+((clk&12)>>2);
8981 dummy_int[1]=0; //no additional tiles
8982 break;
8983
8984 case left:
8985 tile+=21+((clk&12)>>1);
8986 xofs=16;
8987 dummy_int[1]=-1; //second tile is previous tile
8988 break;
8989
8990 case right:
8991 flip=0;
8992 tile+=41+((clk&12)>>1);
8993 xofs=16;
8994 dummy_int[1]=-1; //second tile is previous tile
8995 break;
8996 }
8997 }
8998 }
8999 break;
9000
9001 case aDONGOBS:
9002 {
9003 int32_t fr4=0;
9004
9005 if(!dying && clk2>0 && clk2<=64)
9006 {
9007 // bloated
9008 if(clk2>=0)
9009 {
9010 fr4=3;
9011 }
9012
9013 if(clk2>=16)
9014 {
9015 fr4=2;
9016 }
9017
9018 if(clk2>=32)
9019 {
9020 fr4=1;
9021 }
9022
9023 if(clk2>=48)
9024 {
9025 fr4=0;
9026 }
9027
9028 switch(dir)
9029 {
9030 case up:
9031 tile+=28+fr4;
9032 yofs+=8;
9033 dummy_int[1]=-20; //second tile change
9034 dummy_int[2]=0; //new xofs change
9035 dummy_int[3]=-16; //new xofs change
9036 break;
9037
9038 case down:
9039 tile+=12+fr4;
9040 yofs-=8;
9041 dummy_int[1]=20; //second tile change
9042 dummy_int[2]=0; //new xofs change
9043 dummy_int[3]=16; //new xofs change
9044 break;
9045
9046 case left:
9047 tile+=49+(2*fr4);
9048 xofs+=8;
9049 dummy_int[1]=-1; //second tile change
9050 dummy_int[2]=-16; //new xofs change
9051 dummy_int[3]=0; //new xofs change
9052 break;
9053
9054 case right:
9055 tile+=69+(2*fr4);
9056 xofs+=8;
9057 dummy_int[1]=-1; //second tile change
9058 dummy_int[2]=-16; //new xofs change
9059 dummy_int[3]=0; //new xofs change
9060 break;
9061 }
9062 }
9063 else if(!dying || clk2>19)
9064 {
9065 // normal
9066 switch(dir)
9067 {
9068 case up:
9069 tile+=20+((clk&24)>>3);
9070 yofs+=8;
9071 dummy_int[1]=-20; //second tile change
9072 dummy_int[2]=0; //new xofs change
9073 dummy_int[3]=-16; //new xofs change
9074 break;
9075
9076 case down:
9077 tile+=4+((clk&24)>>3);
9078 yofs-=8;
9079 dummy_int[1]=20; //second tile change
9080 dummy_int[2]=0; //new xofs change
9081 dummy_int[3]=16; //new xofs change
9082 break;
9083
9084 case left:
9085 xofs=-8;
9086 tile+=40+((clk&24)>>2);
9087 dummy_int[1]=1; //second tile change
9088 dummy_int[2]=16; //new xofs change
9089 dummy_int[3]=0; //new xofs change
9090 break;
9091
9092 case right:
9093 tile+=60+((clk&24)>>2);
9094 xofs=-8;
9095 dummy_int[1]=1; //second tile change
9096 dummy_int[2]=16; //new xofs change
9097 dummy_int[3]=0; //new xofs change
9098 break;
9099 }
9100 }
9101 }
9102 break;
9103
9104 case aWIZZ:
9105 {
9106 // if(d->misc1)
9107 if(dmisc1)
9108 {
9109 if(clk&8)
9110 {
9111 ++tile;
9112 }
9113 }
9114 else
9115 {
9116 if(frame&4)
9117 {
9118 ++tile;
9119 }
9120 }
9121
9122 switch(dir)
9123 {
9124 case 9:
9125 case 15:
9126 case up:
9127 tile+=2;
9128 break;
9129
9130 case down:
9131 break;
9132
9133 case 13:
9134 case left:
9135 flip=1;
9136 break;
9137
9138 default:
9139 flip=0;
9140 break;
9141 }
9142 }
9143 break;
9144
9145 case aNEWWIZZ:
9146 {
9147 tiledir(dir,true);
9148
9149 // if(d->misc1) //walking wizzrobe
9150 if(dmisc1) //walking wizzrobe
9151 {
9152 if(clk&8)
9153 {
9154 tile+=2;
9155 }
9156
9157 if(clk&4)
9158 {
9159 tile+=1;
9160 }
9161
9162 if(!(dummy_bool[1]||dummy_bool[2])) //should never be charging or firing for these wizzrobes
9163 {
9164 if(dummy_int[1]>0)
9165 {
9166 tile+=40;
9167 }
9168 }
9169 }
9170 else
9171 {
9172 if(dummy_bool[1]||dummy_bool[2])
9173 {
9174 tile+=20;
9175
9176 if(dummy_bool[2])
9177 {
9178 tile+=20;
9179 }
9180 }
9181
9182 tile+=((frame>>1)&3);
9183 }
9184 }
9185 break;
9186
9187 case a3FRM:
9188 {
9189 basetile = n_frame_n_dir(3, 0, (f4==3) ? 1 : f4);
9190 }
9191 break;
9192
9193 case a3FRM4DIR:
9194 {
9195 basetile = n_frame_n_dir(3, 4, (f4==3) ? 1 : f4);
9196 }
9197 break;
9198
9199 case aVIRE:
9200 {
9201 if(dir==up)
9202 {
9203 tile+=2;
9204 }
9205
9206 tile+=fx;
9207 }
9208 break;
9209
9210 case aROPE:
9211 {
9212 tile+=(1-fx);
9213 flip = dir==left ? 1:0;
9214 }
9215 break;
9216
9217 case aZORA:
9218 {
9219 int32_t dl;
9220
9221
2/2
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 822 times.
1053 if(clk<36)
9222 {
9223 231 dl=clk+5;
9224 231 goto waves2;
9225 }
9226
9227
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 402 times.
822 if(clk<36+66)
9228
2/2
✓ Branch 0 taken 198 times.
✓ Branch 1 taken 222 times.
420 tile=(dir==up)?o_tile+1:o_tile;
9229 else
9230 {
9231 402 dl=clk-36-66;
9232 waves2:
9233 633 tile=((dl/11)&1)+s_tile;
9234 633 basetile = s_tile;
9235 }
9236 }
9237 1053 break;
9238
9239 case aNEWZORA:
9240 {
9241 2952 f4=(clk/16)%4;
9242
9243 2952 tiledir(dir,true);
9244 int32_t dl;
9245
9246
4/4
✓ Branch 0 taken 2364 times.
✓ Branch 1 taken 588 times.
✓ Branch 2 taken 1290 times.
✓ Branch 3 taken 1074 times.
2952 if((clk>35)&&(clk<36+67)) //surfaced
9247 {
9248
4/4
✓ Branch 0 taken 921 times.
✓ Branch 1 taken 153 times.
✓ Branch 2 taken 135 times.
✓ Branch 3 taken 786 times.
1074 if((clk>=(35+10))&&(clk<(38+56))) //mouth open
9249 {
9250 786 tile+=80;
9251 786 } //mouth closed
9252 else
9253 {
9254 288 tile+=40;
9255 }
9256
9257 1074 tile+=f4;
9258 1074 }
9259 else
9260 {
9261
2/2
✓ Branch 0 taken 588 times.
✓ Branch 1 taken 1290 times.
1878 if(clk<36)
9262 {
9263 588 dl=clk+5;
9264 588 }
9265 else
9266 {
9267 1290 dl=clk-36-66;
9268 }
9269
9270 1878 tile+=((dl/5)&3);
9271 }
9272 }
9273 2952 break;
9274
9275 case a4FRM4EYE:
9276 case a2FRM4EYE:
9277 case a4FRM8EYE:
9278 case a4FRM8EYEB: //big version
9279 case a4FRM4EYEB:
9280 {
9281 tilerows = 2;
9282 int fakex = x + 8*(zc_max(1,txsz)-1);
9283 int fakey = y + 8*(zc_max(1,tysz)-1);
9284 double _MSVC2022_tmp1, _MSVC2022_tmp2;
9285 double ddir=atan2_MSVC2022_FIX(double(fakey-(Hero.y)),double(Hero.x-fakex));
9286 int32_t lookat=zc_oldrand()&15;
9287
9288 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
9289 {
9290 lookat=l_down;
9291 }
9292 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
9293 {
9294 lookat=down;
9295 }
9296 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
9297 {
9298 lookat=r_down;
9299 }
9300 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
9301 {
9302 lookat=right;
9303 }
9304 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
9305 {
9306 lookat=r_up;
9307 }
9308 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
9309 {
9310 lookat=up;
9311 }
9312 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
9313 {
9314 lookat=l_up;
9315 }
9316 else
9317 {
9318 lookat=left;
9319 }
9320
9321 int32_t dir2 = dir;
9322 dir = lookat;
9323 if (anim != a4FRM8EYEB && anim != a4FRM4EYEB) basetile = n_frame_n_dir(anim==a2FRM4EYE ? 2:4, anim==a4FRM8EYE ? 8 : 4, anim==a2FRM4EYE ? (f2&1):f4);
9324 else
9325 {
9326 tiledir_big(dir,(anim == a4FRM4EYEB));
9327 tile+=2*f4;
9328 ignore_extend = true;
9329 }
9330 dir = dir2;
9331 }
9332 break;
9333
9334 case aFLIP:
9335 {
9336 16892 flip = f2&1;
9337 }
9338 16892 break;
9339
9340 case a2FRM:
9341 {
9342 3515 tile += (1-f2);
9343 }
9344 3515 break;
9345
9346 case a2FRMB:
9347 {
9348 tile+= 2*(1-f2);
9349 ignore_extend = true;
9350 }
9351 break;
9352
9353 case a2FRM4DIR:
9354 {
9355 basetile = n_frame_n_dir(2, 4, f2&1);
9356 }
9357 break;
9358
9359 case a4FRM4DIRF:
9360 {
9361 91888 basetile = n_frame_n_dir(4,4,f4);
9362
9363
2/2
✓ Branch 0 taken 60019 times.
✓ Branch 1 taken 31869 times.
91888 if(clk2>0) //stopped to fire
9364 {
9365 31869 tile+=20;
9366
9367
2/2
✓ Branch 0 taken 20684 times.
✓ Branch 1 taken 11185 times.
31869 if(clk2<17) //firing
9368 {
9369 11185 tile+=20;
9370 11185 }
9371 31869 }
9372 }
9373 91888 break;
9374
9375 case a4FRM4DIR:
9376 {
9377 12051 basetile = n_frame_n_dir(4,4,f4);
9378 }
9379 12051 break;
9380
9381 case a4FRM8DIRF:
9382 {
9383 tilerows = 2;
9384 basetile = n_frame_n_dir(4,8,f4);
9385
9386 if(clk2>0) //stopped to fire
9387 {
9388 tile+=40;
9389
9390 if(clk2<17) //firing
9391 {
9392 tile+=40;
9393 }
9394 }
9395 }
9396 break;
9397
9398 case a4FRM8DIRB:
9399 case a4FRM8DIRFB:
9400 {
9401 tilerows = 2;
9402 tiledir_big(dir,false);
9403 tile+=2*f4;
9404 if(clk2>0 && anim == a4FRM8DIRFB) //stopped to fire
9405 {
9406 tile+=80;
9407
9408 if(clk2<17) //firing
9409 {
9410 tile+=80;
9411 }
9412 }
9413 ignore_extend = true;
9414 }
9415 break;
9416
9417 case a4FRM4DIRB:
9418 case a4FRM4DIRFB:
9419 {
9420 tilerows = 2;
9421 tiledir_big(dir,true);
9422 tile+=2*f4;
9423 if(clk2>0 && anim == a4FRM4DIRFB) //stopped to fire
9424 {
9425 tile+=40;
9426
9427 if(clk2<17) //firing
9428 {
9429 tile+=40;
9430 }
9431 }
9432 ignore_extend = true;
9433 }
9434 break;
9435
9436 case aOCTO:
9437 {
9438
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 2133 times.
✓ Branch 2 taken 1369 times.
✓ Branch 3 taken 2964 times.
✓ Branch 4 taken 3236 times.
9702 switch(dir)
9439 {
9440 case up:
9441 2133 flip = 2;
9442 2133 break;
9443
9444 case down:
9445 1369 flip = 0;
9446 1369 break;
9447
9448 case left:
9449 2964 flip = 0;
9450 2964 tile += 2;
9451 2964 break;
9452
9453 case right:
9454 3236 flip = 1;
9455 3236 tile += 2;
9456 3236 break;
9457 }
9458
9459 9702 tile+=f2;
9460 }
9461 9702 break;
9462
9463 case aWALK:
9464 {
9465
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1760 times.
✓ Branch 2 taken 2925 times.
✓ Branch 3 taken 2707 times.
✓ Branch 4 taken 1844 times.
9236 switch(dir)
9466 {
9467 case up:
9468 1760 tile+=3;
9469 1760 flip = f2;
9470 1760 break;
9471
9472 case down:
9473 2925 tile+=2;
9474 2925 flip = f2;
9475 2925 break;
9476
9477 case left:
9478 2707 flip=1;
9479 2707 tile += f2;
9480 2707 break;
9481
9482 case right:
9483 1844 flip=0;
9484 1844 tile += f2;
9485 1844 break;
9486 }
9487 }
9488 9236 break;
9489
9490 case aDWALK:
9491 {
9492
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 884 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
884 if((get_bit(quest_rules,qr_BRKNSHLDTILES)) && (dummy_bool[1]==true))
9493 {
9494 tile=s_tile;
9495 basetile = s_tile;
9496 }
9497
9498
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 196 times.
✓ Branch 2 taken 216 times.
✓ Branch 3 taken 256 times.
✓ Branch 4 taken 216 times.
884 switch(dir)
9499 {
9500 case up:
9501 196 tile+=2;
9502 196 flip=f2;
9503 196 break;
9504
9505 case down:
9506 216 flip=0;
9507 216 tile+=(1-f2);
9508 216 break;
9509
9510 case left:
9511 256 flip=1;
9512 256 tile+=(3+f2);
9513 256 break;
9514
9515 case right:
9516 216 flip=0;
9517 216 tile+=(3+f2);
9518 216 break;
9519 }
9520 }
9521 884 break;
9522
9523 case aTEK:
9524 {
9525
2/2
✓ Branch 0 taken 2282 times.
✓ Branch 1 taken 395 times.
2677 if(misc==0)
9526 {
9527 395 tile += f2;
9528 395 }
9529
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 1082 times.
2282 else if(misc!=1)
9530 {
9531 1082 ++tile;
9532 1082 }
9533 }
9534 2677 break;
9535
9536 case aNEWTEK:
9537 {
9538
2/2
✓ Branch 0 taken 1207 times.
✓ Branch 1 taken 8257 times.
9464 if(step<0) //up
9539 {
9540
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 922 times.
✓ Branch 2 taken 285 times.
1207 switch(clk3)
9541 {
9542 case left:
9543 922 flip=0;
9544 922 tile+=20;
9545 922 break;
9546
9547 case right:
9548 285 flip=0;
9549 285 tile+=24;
9550 285 break;
9551 }
9552 1207 }
9553
2/2
✓ Branch 0 taken 726 times.
✓ Branch 1 taken 7531 times.
8257 else if(step==0)
9554 {
9555
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 708 times.
✓ Branch 2 taken 18 times.
726 switch(clk3)
9556 {
9557 case left:
9558 708 flip=0;
9559 708 tile+=8;
9560 708 break;
9561
9562 case right:
9563 18 flip=0;
9564 18 tile+=12;
9565 18 break;
9566 }
9567 726 } //down
9568 else
9569 {
9570
3/3
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 5292 times.
✓ Branch 2 taken 2037 times.
7531 switch(clk3)
9571 {
9572 case left:
9573 5292 flip=0;
9574 5292 tile+=28;
9575 5292 break;
9576
9577 case right:
9578 2037 flip=0;
9579 2037 tile+=32;
9580 2037 break;
9581 }
9582 }
9583
9584
2/2
✓ Branch 0 taken 3977 times.
✓ Branch 1 taken 5487 times.
9464 if(misc==0)
9585 {
9586 5487 tile+=f4;
9587 5487 }
9588
2/2
✓ Branch 0 taken 1645 times.
✓ Branch 1 taken 2332 times.
3977 else if(misc!=1)
9589 {
9590 2332 tile+=2;
9591 2332 }
9592 }
9593 9464 break;
9594
9595 case aARMOS:
9596 {
9597 if(!fading)
9598 {
9599 tile += fx;
9600
9601 if(dir==up)
9602 tile += 2;
9603 }
9604 }
9605 break;
9606
9607 case aARMOS4:
9608 {
9609 switch(dir)
9610 {
9611 case up:
9612 flip=0;
9613 break;
9614
9615 case down:
9616 flip=0;
9617 tile+=4;
9618 break;
9619
9620 case left:
9621 flip=0;
9622 tile+=8;
9623 break;
9624
9625 case right:
9626 flip=0;
9627 tile+=12;
9628 break;
9629 }
9630
9631 if(!fading)
9632 {
9633 tile+=f4;
9634 }
9635 }
9636 break;
9637
9638 case aGHINI:
9639 {
9640 switch(dir)
9641 {
9642 case 8:
9643 case 9:
9644 case up:
9645 ++tile;
9646 flip=0;
9647 break;
9648
9649 case 15:
9650 ++tile;
9651 flip=1;
9652 break;
9653
9654 case 10:
9655 case 11:
9656 case right:
9657 flip=1;
9658 break;
9659
9660 default:
9661 flip=0;
9662 break;
9663 }
9664 }
9665 break;
9666
9667 case a2FRMPOS:
9668 {
9669 16798 tile+=posframe;
9670 }
9671 16798 break;
9672
9673 case a4FRMPOS4DIR:
9674 {
9675 basetile = n_frame_n_dir(4,4,0);
9676 // tile+=f2;
9677 tile+=posframe;
9678 }
9679 break;
9680
9681 case a4FRMPOS4DIRF:
9682 {
9683 basetile = n_frame_n_dir(4,4,0);
9684
9685 if(clk2>0) //stopped to fire
9686 {
9687 tile+=20;
9688
9689 if(clk2<17) //firing
9690 {
9691 tile+=20;
9692 }
9693 }
9694
9695 // tile+=f2;
9696 tile+=posframe;
9697 }
9698 break;
9699
9700 case a4FRMPOS8DIR:
9701 {
9702 39193 tilerows = 2;
9703 39193 int32_t n = tile;
9704 39193 basetile = n_frame_n_dir(4,8,0);
9705 // tile+=f2;
9706 39193 tile+=posframe;
9707 }
9708 39193 break;
9709
9710 case a4FRMPOS8DIRF:
9711 {
9712 tilerows = 2;
9713 basetile = n_frame_n_dir(4,8,0);
9714
9715 if(clk2>0) //stopped to fire
9716 {
9717 tile+=40;
9718
9719 if(clk2<17) //firing
9720 {
9721 tile+=40;
9722 }
9723 }
9724
9725 tile+=posframe;
9726 }
9727 break;
9728
9729 case aNEWLEV:
9730 {
9731 tiledir(dir,true);
9732
9733 switch(misc)
9734 {
9735 case -1:
9736 case 0:
9737 return;
9738
9739 case 1:
9740
9741 // case 5: cs = d->misc2; break;
9742 case 5:
9743 cs = dmisc2;
9744 break;
9745
9746 case 2:
9747 case 4:
9748 tile += 20;
9749 break;
9750
9751 case 3:
9752 tile += 40;
9753 break;
9754 }
9755
9756 tile+=f4;
9757 }
9758 break;
9759
9760 case aLEV:
9761 {
9762 721 f4 = ((clk/5)&1);
9763
9764
4/5
✓ Branch 0 taken 427 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 219 times.
721 switch(misc)
9765 {
9766 case -1:
9767 case 0:
9768 427 return;
9769
9770 case 1:
9771
9772 // case 5: tile += (f2) ? 1 : 0; cs = d->misc2; break;
9773 case 5:
9774 51 tile += (f2) ? 1 : 0;
9775 51 cs = dmisc2;
9776 51 break;
9777
9778 case 2:
9779 case 4:
9780 24 tile += 2;
9781 24 break;
9782
9783 case 3:
9784 219 tile += (f4) ? 4 : 3;
9785 219 break;
9786 }
9787 }
9788 294 break;
9789
9790 case aWALLM:
9791 {
9792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4548 times.
4548 if(!dummy_bool[1])
9793 {
9794 4548 tile += f2;
9795 4548 }
9796 }
9797 4548 break;
9798
9799 case aNEWWALLM:
9800 {
9801 3737 int32_t tempdir=0;
9802
9803
3/4
✓ Branch 0 taken 1553 times.
✓ Branch 1 taken 740 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1444 times.
3737 switch(misc)
9804 {
9805 case 1:
9806 case 2:
9807 740 tempdir=clk3;
9808 740 break;
9809
9810 case 3:
9811 case 4:
9812 case 5:
9813 1553 tempdir=dir;
9814 1553 break;
9815
9816 case 6:
9817 case 7:
9818 tempdir=clk3^1;
9819 break;
9820 }
9821
9822 3737 tiledir(tempdir,true);
9823
9824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3737 times.
3737 if(!dummy_bool[1])
9825 {
9826 3737 tile+=f4;
9827 3737 }
9828 }
9829 3737 break;
9830
9831 case a4FRMNODIR:
9832 {
9833 tile+=f4;
9834 }
9835 break;
9836
9837 } // switch(d->anim)
9838
9839 // flashing
9840 // if(d->flags2 & guy_flashing)
9841
2/2
✓ Branch 0 taken 227443 times.
✓ Branch 1 taken 2696 times.
230139 if(flags2 & guy_flashing)
9842 {
9843 2696 cs = (frame&3) + 6;
9844 2696 }
9845
9846
1/2
✓ Branch 0 taken 230139 times.
✗ Branch 1 not taken.
230139 if(flags2&guy_transparent)
9847 {
9848 drawstyle=1;
9849 }
9850
9851 230139 int32_t change = tile-basetile;
9852
9853
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 230139 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
230139 if(extend > 2 && (!ignore_extend || get_bit(quest_rules, qr_BROKEN_BIG_ENEMY_ANIMATION)))
9854 {
9855 if(basetile/TILES_PER_ROW==(basetile+((txsz*change)/tilerows))/TILES_PER_ROW)
9856 {
9857 tile=basetile+txsz*change;
9858 }
9859 else
9860 {
9861 tile=basetile+(txsz*change)+((tysz-1)*TILES_PER_ROW)*(((basetile+txsz*change)/TILES_PER_ROW)-(basetile/TILES_PER_ROW));
9862 }
9863 }
9864 else
9865 {
9866 230139 tile=basetile+change;
9867 }
9868 230566 }
9869
9870 220 int32_t wpnsfx(int32_t wpn)
9871 {
9872
3/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 56 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 130 times.
220 switch(wpn)
9873 {
9874 case ewFireTrail:
9875 case ewFlame:
9876 case ewFlame2Trail:
9877 case ewFlame2:
9878 return WAV_FIRE;
9879
9880 case ewWind:
9881 case ewMagic:
9882 return WAV_WAND;
9883
9884 case ewIce:
9885 return WAV_ZN1ICE;
9886
9887 case ewRock:
9888
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 if(get_bit(quest_rules,qr_MORESOUNDS)) return WAV_ZN1ROCK;
9889 130 break;
9890
9891 case ewFireball2:
9892 case ewFireball:
9893
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if(get_bit(quest_rules,qr_MORESOUNDS)) return WAV_ZN1FIREBALL;
9894 34 }
9895
9896 220 return -1;
9897 220 }
9898
9899 389245 int32_t enemy::run_script(int32_t mode)
9900 {
9901
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 389245 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
389245 if(switch_hooked && !get_bit(quest_rules, qr_SWITCHOBJ_RUN_SCRIPT)) return RUNSCRIPT_OK;
9902
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 389245 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
389245 if (script <= 0 || !doscript || FFCore.getQuestHeaderInfo(vZelda) < 0x255 || FFCore.system_suspend[susptNPCSCRIPTS])
9903 389245 return RUNSCRIPT_OK;
9904 int32_t ret = RUNSCRIPT_OK;
9905 alloc_scriptmem();
9906 switch(mode)
9907 {
9908 case MODE_NORMAL:
9909 return ZScriptVersion::RunScript(SCRIPT_NPC, script, getUID());
9910 case MODE_WAITDRAW:
9911 if(waitdraw)
9912 {
9913 ret = ZScriptVersion::RunScript(SCRIPT_NPC, script, getUID());
9914 waitdraw = 0;
9915 }
9916 break;
9917 }
9918 return ret;
9919 389245 }
9920
9921 /********************************/
9922 /********* Guy Class **********/
9923 /********************************/
9924
9925 // good guys, fires, fairy, and other non-enemies
9926 // based on enemy class b/c guys in dungeons act sort of like enemies
9927 // also easier to manage all the guys this way
9928 58 guy::guy(zfix X,zfix Y,int32_t Id,int32_t Clk,bool mg) : enemy(X,Y,Id,Clk)
9929 58 {
9930 29 mainguy=mg;
9931 29 canfreeze=false;
9932 29 dir=down;
9933
3/6
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 29 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
29 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
9934 29 hxofs=2;
9935 29 hzsz=8;
9936 29 hxsz=12;
9937 29 hysz=17;
9938
9939
8/12
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 3 times.
29 if(!superman && (!isdungeon() || id==gFAIRY || id==gFIRE || id==gZELDA))
9940 {
9941 26 superman = 1;
9942 26 hxofs=1000;
9943 26 }
9944 29 }
9945
9946 12436 bool guy::animate(int32_t index)
9947 {
9948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12436 times.
12436 if(switch_hooked) return enemy::animate(index);
9949
6/6
✓ Branch 0 taken 4830 times.
✓ Branch 1 taken 7606 times.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 4805 times.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 13 times.
12436 if(mainguy && clk==0 && misc==0)
9950 {
9951 13 setupscreen();
9952 13 misc = 1;
9953 13 }
9954
9955
4/4
✓ Branch 0 taken 4830 times.
✓ Branch 1 taken 7606 times.
✓ Branch 2 taken 4822 times.
✓ Branch 3 taken 8 times.
12436 if(mainguy && fadeclk==0)
9956 8 return true;
9957
9958 12428 hp=256; // good guys never die...
9959
9960
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 12395 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 1 times.
12428 if(hclk && !clk2)
9961 {
9962 // but if they get hit...
9963 1 ++clk2; // only do this once
9964
9965
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(!get_bit(quest_rules,qr_NOGUYFIRES))
9966 {
9967 1 addenemy(BSZ?64:72,68,eSHOOTFBALL,0);
9968 1 addenemy(BSZ?176:168,68,eSHOOTFBALL,0);
9969 1 }
9970 1 }
9971
9972 12428 return enemy::animate(index);
9973 12436 }
9974
9975 12475 void guy::draw(BITMAP *dest)
9976 {
9977 12475 update_enemy_frame();
9978
9979
6/6
✓ Branch 0 taken 4843 times.
✓ Branch 1 taken 7632 times.
✓ Branch 2 taken 528 times.
✓ Branch 3 taken 4315 times.
✓ Branch 4 taken 264 times.
✓ Branch 5 taken 264 times.
12475 if(!mainguy || fadeclk<0 || fadeclk&1)
9980 12211 enemy::draw(dest);
9981 12475 }
9982
9983 /*******************************/
9984 /********* Enemies *********/
9985 /*******************************/
9986
9987 eFire::eFire(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
9988 {
9989 clk4=0;
9990 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
9991 // Spawn type
9992 if(flags & guy_fadeflicker)
9993 {
9994 clk=0;
9995 superman = 1;
9996 fading=fade_flicker;
9997 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
9998 dir=down;
9999
10000 if(!canmove(down,(zfix)8,spw_none,false))
10001 clk3=int32_t(13.0/step);
10002 }
10003 else if(flags & guy_fadeinstant)
10004 {
10005 clk=0;
10006 }
10007 SIZEflags = d->SIZEflags;
10008 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10009 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10010 // al_trace("Enemy txsz:%i\n", txsz);
10011 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10012 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10013 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10014 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10015 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10016 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10017 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10018 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10019 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10020 {
10021 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10022 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10023 }
10024
10025 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) d->zofs = (int32_t)zofs;
10026 }
10027
10028 bool eFire::animate(int32_t index)
10029 {
10030 if(switch_hooked) return enemy::animate(index);
10031 if(fallclk||drownclk) return enemy::animate(index);
10032 if(fading)
10033 {
10034 if(++clk4 > 60)
10035 {
10036 clk4=0;
10037 superman=0;
10038 fading=0;
10039
10040 if(flags2&cmbflag_armos && z==0 && fakez==0)
10041 removearmos(x,y,ffcactivated);
10042
10043 clk2=0;
10044
10045 if(!canmove(down,(zfix)8,spw_none,false))
10046 {
10047 dir=0;
10048 y = y.getInt() & 0xF0;
10049 }
10050
10051 return Dead(index);
10052 }
10053 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10054 removearmos(x,y,ffcactivated);
10055 }
10056
10057 return enemy::animate(index);
10058 }
10059
10060 void eFire::draw(BITMAP *dest)
10061 {
10062 update_enemy_frame();
10063 enemy::draw(dest);
10064 }
10065
10066 int32_t eFire::takehit(weapon *w)
10067 {
10068 int32_t wpnId = w->id;
10069 int32_t wpnDir = w->dir;
10070
10071 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10072 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10073 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10074 {
10075 shield = false;
10076 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10077
10078 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10079 o_tile=s_tile;
10080 }
10081
10082 int32_t ret = enemy::takehit(w);
10083 return ret;
10084 }
10085
10086 void eFire::break_shield()
10087 {
10088 if(!shield)
10089 return;
10090
10091 flags&=~(inv_front | inv_back | inv_left | inv_right);
10092 shield=false;
10093
10094 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10095 o_tile=s_tile;
10096 }
10097
10098 eOther::eOther(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10099 {
10100 //zprint2("npct other::other\n");
10101 clk4=0;
10102 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
10103
10104 // Spawn type
10105 if(flags & guy_fadeflicker)
10106 {
10107 clk=0;
10108 superman = 1;
10109 fading=fade_flicker;
10110 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10111 dir=down;
10112
10113 if(!canmove(down,(zfix)8,spw_none,false))
10114 clk3=int32_t(13.0/step);
10115 }
10116 else if(flags & guy_fadeinstant)
10117 {
10118 clk=0;
10119 }
10120 SIZEflags = d->SIZEflags;
10121 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10122 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10123 // al_trace("Enemy txsz:%i\n", txsz);
10124 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10125 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10126 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10127 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10128 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10129 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10130 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10131 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10132 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10133 {
10134 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10135 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10136 }
10137
10138 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10139 }
10140
10141 bool eOther::animate(int32_t index)
10142 {
10143 if(switch_hooked) return enemy::animate(index);
10144 if(fallclk||drownclk) return enemy::animate(index);
10145 //zprint2("npct other::animate\n");
10146 if(fading)
10147 {
10148 if(++clk4 > 60)
10149 {
10150 clk4=0;
10151 superman=0;
10152 fading=0;
10153
10154 if(flags2&cmbflag_armos && z==0 && fakez==0)
10155 removearmos(x,y,ffcactivated);
10156
10157 clk2=0;
10158
10159 if(!canmove(down,(zfix)8,spw_none,false))
10160 {
10161 dir=0;
10162 y = y.getInt() & 0xF0;
10163 }
10164
10165 return Dead(index);
10166 }
10167 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10168 removearmos(x,y,ffcactivated);
10169 }
10170
10171 return enemy::animate(index);
10172 }
10173
10174 void eOther::draw(BITMAP *dest)
10175 {
10176 update_enemy_frame();
10177 enemy::draw(dest);
10178 }
10179
10180 int32_t eOther::takehit(weapon *w)
10181 {
10182 int32_t wpnId = w->id;
10183 int32_t wpnDir = w->dir;
10184
10185 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10186 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10187 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10188 {
10189 shield = false;
10190 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10191
10192 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10193 o_tile=s_tile;
10194 }
10195
10196 int32_t ret = enemy::takehit(w);
10197 return ret;
10198 }
10199
10200 void eOther::break_shield()
10201 {
10202 if(!shield)
10203 return;
10204
10205 flags&=~(inv_front | inv_back | inv_left | inv_right);
10206 shield=false;
10207
10208 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10209 o_tile=s_tile;
10210 }
10211
10212
10213 eScript::eScript(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10214 {
10215 clk4=0;
10216 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
10217
10218 // Spawn type
10219 if(flags & guy_fadeflicker)
10220 {
10221 clk=0;
10222 superman = 1;
10223 fading=fade_flicker;
10224 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10225 dir=down;
10226
10227 if(!canmove(down,(zfix)8,spw_none,false))
10228 clk3=int32_t(13.0/step);
10229 }
10230 else if(flags & guy_fadeinstant)
10231 {
10232 clk=0;
10233 }
10234 SIZEflags = d->SIZEflags;
10235 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10236 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10237 // al_trace("Enemy txsz:%i\n", txsz);
10238 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10239 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10240 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10241 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10242 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10243 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10244 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10245 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10246 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10247 {
10248 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10249 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10250 }
10251
10252 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10253 }
10254
10255 bool eScript::animate(int32_t index)
10256 {
10257 if(switch_hooked) return enemy::animate(index);
10258 if(fallclk||drownclk) return enemy::animate(index);
10259 if(fading)
10260 {
10261 if(++clk4 > 60)
10262 {
10263 clk4=0;
10264 superman=0;
10265 fading=0;
10266
10267 if(flags2&cmbflag_armos && z==0 && fakez==0)
10268 removearmos(x,y,ffcactivated);
10269
10270 clk2=0;
10271
10272 if(!canmove(down,(zfix)8,spw_none,false))
10273 {
10274 dir=0;
10275 y = y.getInt() & 0xF0;
10276 }
10277
10278 return Dead(index);
10279 }
10280 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10281 removearmos(x,y,ffcactivated);
10282 }
10283
10284 return enemy::animate(index);
10285 }
10286
10287 void eScript::draw(BITMAP *dest)
10288 {
10289 update_enemy_frame();
10290 enemy::draw(dest);
10291 }
10292
10293 int32_t eScript::takehit(weapon *w)
10294 {
10295 int32_t wpnId = w->id;
10296 int32_t wpnDir = w->dir;
10297
10298 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10299 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10300 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10301 {
10302 shield = false;
10303 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10304
10305 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10306 o_tile=s_tile;
10307 }
10308
10309 int32_t ret = enemy::takehit(w);
10310 return ret;
10311 }
10312
10313 void eScript::break_shield()
10314 {
10315 if(!shield)
10316 return;
10317
10318 flags&=~(inv_front | inv_back | inv_left | inv_right);
10319 shield=false;
10320
10321 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10322 o_tile=s_tile;
10323 }
10324
10325
10326 eFriendly::eFriendly(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10327 {
10328 clk4=0;
10329 hyofs = -32768; //No hitbox initially.
10330 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
10331
10332 // Spawn type
10333 if(flags & guy_fadeflicker)
10334 {
10335 clk=0;
10336 superman = 1;
10337 fading=fade_flicker;
10338 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10339 dir=down;
10340
10341 if(!canmove(down,(zfix)8,spw_none,false))
10342 clk3=int32_t(13.0/step);
10343 }
10344 else if(flags & guy_fadeinstant)
10345 {
10346 clk=0;
10347 }
10348 SIZEflags = d->SIZEflags;
10349 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10350 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10351 // al_trace("Enemy txsz:%i\n", txsz);
10352 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10353 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10354 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10355 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10356 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10357 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10358 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10359 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10360 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10361 {
10362 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10363 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10364 }
10365
10366 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10367 }
10368
10369 bool eFriendly::animate(int32_t index)
10370 {
10371 if(switch_hooked) return enemy::animate(index);
10372 if(fallclk||drownclk) return enemy::animate(index);
10373 if(fading)
10374 {
10375 if(++clk4 > 60)
10376 {
10377 clk4=0;
10378 superman=0;
10379 fading=0;
10380
10381 if(flags2&cmbflag_armos && z==0 && fakez==0)
10382 removearmos(x,y,ffcactivated);
10383
10384 clk2=0;
10385
10386 if(!canmove(down,(zfix)8,spw_none,false))
10387 {
10388 dir=0;
10389 y = y.getInt() & 0xF0;
10390 }
10391
10392 return Dead(index);
10393 }
10394 else if(flags2&cmbflag_armos && z==0 && fakez==0 && clk==0)
10395 removearmos(x,y,ffcactivated);
10396 }
10397
10398 return enemy::animate(index);
10399 }
10400
10401 void eFriendly::draw(BITMAP *dest)
10402 {
10403 update_enemy_frame();
10404 enemy::draw(dest);
10405 }
10406
10407 int32_t eFriendly::takehit(weapon *w)
10408 {
10409 int32_t wpnId = w->id;
10410 int32_t wpnDir = w->dir;
10411
10412 if(wpnId==wHammer && shield && (flags & guy_bkshield)
10413 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
10414 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
10415 {
10416 shield = false;
10417 flags &= ~(inv_left|inv_right|inv_back|inv_front);
10418
10419 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10420 o_tile=s_tile;
10421 }
10422
10423 int32_t ret = enemy::takehit(w);
10424 return ret;
10425 }
10426
10427 void eFriendly::break_shield()
10428 {
10429 if(!shield)
10430 return;
10431
10432 flags&=~(inv_front | inv_back | inv_left | inv_right);
10433 shield=false;
10434
10435 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
10436 o_tile=s_tile;
10437 }
10438
10439
10440 786 void enemy::removearmos(int32_t ax,int32_t ay, word ffcactive)
10441 {
10442
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 786 times.
786 if (ffcactive)
10443 {
10444 removearmosffc(ffcactive-1);
10445 return;
10446 }
10447
1/2
✓ Branch 0 taken 786 times.
✗ Branch 1 not taken.
786 if(did_armos)
10448 {
10449 786 return;
10450 }
10451
10452 did_armos=true;
10453 ax&=0xF0;
10454 ay&=0xF0;
10455 int32_t cd = (ax>>4)+ay;
10456 int32_t f = MAPFLAG(ax,ay);
10457 int32_t f2 = MAPCOMBOFLAG(ax,ay);
10458
10459 if(combobuf[tmpscr->data[cd]].type!=cARMOS)
10460 {
10461 return;
10462 }
10463
10464 tmpscr->data[cd] = tmpscr->undercombo;
10465 tmpscr->cset[cd] = tmpscr->undercset;
10466 tmpscr->sflag[cd] = 0;
10467
10468 if(f == mfARMOS_SECRET || f2 == mfARMOS_SECRET)
10469 {
10470 tmpscr->data[cd] = tmpscr->secretcombo[sSTAIRS];
10471 tmpscr->cset[cd] = tmpscr->secretcset[sSTAIRS];
10472 tmpscr->sflag[cd]=tmpscr->secretflag[sSTAIRS];
10473 sfx(tmpscr->secretsfx);
10474 }
10475
10476 if(f == mfARMOS_ITEM || f2 == mfARMOS_ITEM)
10477 {
10478 if(!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr->flags9&fBELOWRETURN))
10479 {
10480 additem(ax,ay,tmpscr->catchall, (ipONETIME2 + ipBIGRANGE) | ((tmpscr->flags3&fHOLDITEM) ? ipHOLDUP : 0) | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0));
10481 sfx(tmpscr->secretsfx);
10482 }
10483 }
10484
10485 putcombo(scrollbuf,ax,ay,tmpscr->data[cd],tmpscr->cset[cd]);
10486 786 }
10487
10488 void enemy::removearmosffc(int32_t pos)
10489 {
10490 if(did_armos)
10491 {
10492 return;
10493 }
10494
10495 did_armos=true;
10496 ffcdata& ffc = tmpscr->ffcs[pos];
10497 newcombo const& cmb = combobuf[ffc.getData()];
10498 int32_t f2 = cmb.flag;
10499
10500 if(cmb.type!=cARMOS)
10501 {
10502 return;
10503 }
10504
10505 ffc.setData(tmpscr->undercombo);
10506 ffc.cset = tmpscr->undercset;
10507
10508 if(f2 == mfARMOS_SECRET)
10509 {
10510 ffc.setData(tmpscr->secretcombo[sSTAIRS]);
10511 ffc.cset = tmpscr->secretcset[sSTAIRS];
10512 sfx(tmpscr->secretsfx);
10513 }
10514
10515 if(f2 == mfARMOS_ITEM)
10516 {
10517 if(!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr->flags9&fBELOWRETURN))
10518 {
10519 additem(ffc.x,ffc.y,tmpscr->catchall, (ipONETIME2 + ipBIGRANGE) | ((tmpscr->flags3&fHOLDITEM) ? ipHOLDUP : 0) | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0));
10520 sfx(tmpscr->secretsfx);
10521 }
10522 }
10523
10524 putcombo(scrollbuf,ffc.x,ffc.y,ffc.getData(),ffc.cset);
10525 }
10526
10527
10528 eGhini::eGhini(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10529 {
10530 fading=fade_flicker;
10531 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
10532 dir=12;
10533 movestatus=1;
10534 step=0;
10535 clk=0;
10536 clk4=0;
10537 SIZEflags = d->SIZEflags;
10538 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10539 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10540 // al_trace("Enemy txsz:%i\n", txsz);
10541 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10542 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10543 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10544 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10545 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10546 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10547 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10548 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10549 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10550 {
10551 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10552 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10553 }
10554
10555 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10556 }
10557
10558 bool eGhini::animate(int32_t index)
10559 {
10560 if(switch_hooked) return enemy::animate(index);
10561 if(fallclk||drownclk) return enemy::animate(index);
10562 if(dying)
10563 return Dead(index);
10564
10565 if(dmisc1)
10566 {
10567 if(misc)
10568 {
10569 if(clk4>160)
10570 misc=2;
10571
10572 floater_walk((misc==1)?0:rate,hrate,zslongToFix(dstep*100),zslongToFix(dstep*10),10,dmisc16,dmisc17); //120,10);
10573 removearmos(x,y,ffcactivated);
10574 }
10575 else if(clk4>=60)
10576 {
10577 misc=1;
10578 clk3=32;
10579 fading=0;
10580 if (ffcactivated > 0)
10581 {
10582 guygridffc[ffcactivated-1] = 0;
10583 removearmosffc(ffcactivated-1);
10584 }
10585 else
10586 {
10587 guygrid[(int32_t(y)&0xF0)+(int32_t(x)>>4)]=0;
10588 removearmos(x,y);
10589 }
10590 }
10591 }
10592
10593 clk4++;
10594
10595 return enemy::animate(index);
10596 }
10597
10598 void eGhini::draw(BITMAP *dest)
10599 {
10600 update_enemy_frame();
10601 enemy::draw(dest);
10602 }
10603
10604 void eGhini::kickbucket()
10605 {
10606 hp=-1000; // don't call death_sfx()
10607 }
10608
10609
3/6
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
57 eTektite::eTektite(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10610 38 {
10611
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 old_y=y;
10612 19 dir=down;
10613 19 misc=1;
10614 19 clk=-15;
10615
10616
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if(!BSZ)
10617
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 clk*=zc_oldrand()%3+1;
10618
10619 // avoid divide by 0 errors
10620
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if(dmisc1 == 0)
10621 dmisc1 = 24;
10622
10623
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if(dmisc2 == 0)
10624 dmisc2 = 3;
10625
10626 //nets+760;
10627 19 SIZEflags = d->SIZEflags;
10628
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10629 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10630 // al_trace("Enemy txsz:%i\n", txsz);
10631
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10632
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10633
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10634
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10635
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10636
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10637 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10638
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10640 {
10641 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10642 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10643 }
10644
10645
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
19 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10646 19 }
10647
10648 5994 bool eTektite::animate(int32_t index)
10649 {
10650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5994 times.
5994 if(switch_hooked) return enemy::animate(index);
10651
4/4
✓ Branch 0 taken 5984 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 5974 times.
5994 if(fallclk||drownclk) return enemy::animate(index);
10652
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 5848 times.
5974 if(dying)
10653 126 return Dead(index);
10654
10655
2/2
✓ Branch 0 taken 5708 times.
✓ Branch 1 taken 140 times.
5848 if(clk==0)
10656 {
10657 140 removearmos(x,y,ffcactivated);
10658 140 }
10659
10660
2/2
✓ Branch 0 taken 2612 times.
✓ Branch 1 taken 3236 times.
5848 if(get_bit(quest_rules,qr_ENEMIESZAXIS))
10661 {
10662 3236 y=floor_y;
10663 3236 }
10664
10665
8/10
✓ Branch 0 taken 5243 times.
✓ Branch 1 taken 605 times.
✓ Branch 2 taken 4959 times.
✓ Branch 3 taken 284 times.
✓ Branch 4 taken 4959 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4959 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 10 times.
5848 if(clk>=0 && !stunclk && !frozenclock && (!watch || misc==0))
10666 {
10667
4/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2111 times.
✓ Branch 2 taken 1249 times.
✓ Branch 3 taken 1599 times.
4969 switch(misc)
10668 {
10669 case 0: // normal
10670
2/2
✓ Branch 0 taken 2071 times.
✓ Branch 1 taken 40 times.
2111 if(!(zc_oldrand()%dmisc1))
10671 {
10672 40 misc=1;
10673 40 clk2=32;
10674 40 }
10675
10676 2111 break;
10677
10678 case 1: // waiting to pounce
10679
2/2
✓ Branch 0 taken 1182 times.
✓ Branch 1 taken 67 times.
1249 if(--clk2<=0)
10680 {
10681 67 int32_t r=zc_oldrand();
10682 67 misc=2;
10683 67 step=0-(zslongToFix(dstep*100)); // initial speed
10684 67 clk3=(r&1)+2; // left or right
10685 67 clk2start=clk2=(r&31)+10; // flight time
10686
10687
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 5 times.
67 if(y<32) clk2+=2; // make them come down from top of screen
10688
10689
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 16 times.
67 if(y>112) clk2-=2; // make them go back up
10690
10691 67 cstart=c = 9-((r&31)>>3); // time before gravity kicks in
10692 67 }
10693
10694 1249 break;
10695
10696 case 2: // in flight
10697 1599 move(step);
10698
10699
2/2
✓ Branch 0 taken 743 times.
✓ Branch 1 taken 856 times.
1599 if(step>0) //going down
10700 {
10701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 743 times.
743 if(COMBOTYPE(x+8,y+16)==cNOJUMPZONE)
10702 {
10703 step=0-step;
10704 }
10705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 743 times.
743 else if(COMBOTYPE(x+8,y+16)==cNOENEMY)
10706 {
10707 step=0-step;
10708 }
10709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 743 times.
743 else if(ispitfall(x+8,y+16))
10710 {
10711 step=0-step;
10712 }
10713
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 743 times.
743 else if(MAPFLAG(x+8,y+16)==mfNOENEMY)
10714 {
10715 step=0-step;
10716 }
10717
1/2
✓ Branch 0 taken 743 times.
✗ Branch 1 not taken.
743 else if(MAPCOMBOFLAG(x+8,y+16)==mfNOENEMY)
10718 {
10719 step=0-step;
10720 }
10721 743 }
10722
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 801 times.
856 else if(step<0)
10723 {
10724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 801 times.
801 if(COMBOTYPE(x+8,y)==cNOJUMPZONE)
10725 {
10726 step=0-step;
10727 }
10728
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 801 times.
801 else if(COMBOTYPE(x+8,y)==cNOENEMY)
10729 {
10730 step=0-step;
10731 }
10732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 801 times.
801 else if(ispitfall(x+8,y))
10733 {
10734 step=0-step;
10735 }
10736
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 801 times.
801 else if(MAPFLAG(x+8,y)==mfNOENEMY)
10737 {
10738 step=0-step;
10739 }
10740
1/2
✓ Branch 0 taken 801 times.
✗ Branch 1 not taken.
801 else if(MAPCOMBOFLAG(x+8,y)==mfNOENEMY)
10741 {
10742 step=0-step;
10743 }
10744 801 }
10745
10746
2/2
✓ Branch 0 taken 912 times.
✓ Branch 1 taken 687 times.
1599 if(clk3==left)
10747 {
10748
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912 times.
912 if(COMBOTYPE(x,y+8)==cNOJUMPZONE)
10749 {
10750 clk3^=1;
10751 }
10752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912 times.
912 else if(COMBOTYPE(x,y+8)==cNOENEMY)
10753 {
10754 clk3^=1;
10755 }
10756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912 times.
912 else if(ispitfall(x,y+8))
10757 {
10758 clk3^=1;
10759 }
10760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 912 times.
912 else if(MAPFLAG(x,y+8)==mfNOENEMY)
10761 {
10762 clk3^=1;
10763 }
10764
1/2
✓ Branch 0 taken 912 times.
✗ Branch 1 not taken.
912 else if(MAPCOMBOFLAG(x,y+8)==mfNOENEMY)
10765 {
10766 clk3^=1;
10767 }
10768 912 }
10769 else
10770 {
10771
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 if(COMBOTYPE(x+16,y+8)==cNOJUMPZONE)
10772 {
10773 clk3^=1;
10774 }
10775
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 else if(COMBOTYPE(x+16,y+8)==cNOENEMY)
10776 {
10777 clk3^=1;
10778 }
10779
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 else if(ispitfall(x+16,y+8))
10780 {
10781 clk3^=1;
10782 }
10783
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 else if(MAPFLAG(x+16,y+8)==mfNOENEMY)
10784 {
10785 clk3^=1;
10786 }
10787
1/2
✓ Branch 0 taken 687 times.
✗ Branch 1 not taken.
687 else if(MAPCOMBOFLAG(x+16,y+8)==mfNOENEMY)
10788 {
10789 clk3^=1;
10790 }
10791 }
10792
10793 1599 --c;
10794
10795
4/4
✓ Branch 0 taken 494 times.
✓ Branch 1 taken 1105 times.
✓ Branch 2 taken 1032 times.
✓ Branch 3 taken 567 times.
1599 if(c<0 && step<zslongToFix(dstep*100))
10796 {
10797 567 step+=zslongToFix(dmisc3*100);
10798 567 }
10799
10800 1599 int32_t nb=get_bit(quest_rules,qr_NOBORDER) ? 16 : 0;
10801
10802
2/2
✓ Branch 0 taken 1597 times.
✓ Branch 1 taken 2 times.
1599 if(x<=16-nb) clk3=right;
10803
10804
2/2
✓ Branch 0 taken 1597 times.
✓ Branch 1 taken 2 times.
1599 if(x>=224+nb) clk3=left;
10805
10806 1599 x += (clk3==left) ? -1 : 1;
10807
10808
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 1534 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1529 times.
1599 if((--clk2<=0 && y>=16-nb) || y>=144+nb)
10809 {
10810
3/4
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
70 if(y>=144+nb && get_bit(quest_rules,qr_ENEMIESZAXIS))
10811 {
10812 step=0-step;
10813 y--;
10814 }
10815
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 12 times.
60 else if(zc_oldrand()%dmisc2) //land and wait
10816 {
10817 48 clk=misc=0;
10818 48 } //land and jump again
10819 else
10820 {
10821 12 misc=1;
10822 12 clk2=0;
10823 }
10824 60 }
10825
10826 1589 break;
10827 } // switch
10828 4959 }
10829
10830
4/4
✓ Branch 0 taken 3236 times.
✓ Branch 1 taken 2622 times.
✓ Branch 2 taken 2474 times.
✓ Branch 3 taken 762 times.
5858 if(get_bit(quest_rules,qr_ENEMIESZAXIS) && misc==2)
10831 {
10832
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 762 times.
762 if (moveflags & FLAG_USE_FAKE_Z)
10833 {
10834 int32_t tempy = floor_y;
10835 fakez=zc_max(0,zc_min(clk2start-clk2,clk2));
10836 floor_y = y;
10837 y=tempy-fakez;
10838 old_y = y;
10839 }
10840 else
10841 {
10842 762 int32_t tempy = floor_y;
10843
6/6
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 478 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 756 times.
✓ Branch 4 taken 278 times.
✓ Branch 5 taken 478 times.
762 z=zc_max(0,zc_min(clk2start-clk2,clk2));
10844 762 floor_y = y;
10845 762 y=tempy-z;
10846 762 old_y = y;
10847 }
10848 762 }
10849
10850
4/4
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 5574 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 261 times.
5858 if(stunclk && (clk&31)==1)
10851 261 clk=0;
10852
10853 5858 return enemy::animate(index);
10854 5984 }
10855
10856 1651 void eTektite::drawshadow(BITMAP *dest,bool translucent)
10857 {
10858
4/6
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 1538 times.
✓ Branch 2 taken 113 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 113 times.
1651 if(z<1 && fakez<1 && get_bit(quest_rules,qr_ENEMIESZAXIS))
10859 113 return;
10860
10861 1538 int32_t tempy=yofs;
10862 1538 int32_t fdiv = frate/4;
10863
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1538 times.
1538 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
10864
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1538 times.
1538 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
10865 1538 efrate:((clk>=(frate>>1))?1:0);
10866 1538 flip = 0;
10867 1538 shadowtile = wpnsbuf[spr_shadow].tile;
10868
10869
1/2
✓ Branch 0 taken 1538 times.
✗ Branch 1 not taken.
1538 if(get_bit(quest_rules,qr_NEWENEMYTILES))
10870 {
10871
2/2
✓ Branch 0 taken 912 times.
✓ Branch 1 taken 626 times.
1538 if(misc==0)
10872 {
10873 912 shadowtile+=f2;
10874 912 }
10875
2/2
✓ Branch 0 taken 241 times.
✓ Branch 1 taken 385 times.
626 else if(misc!=1)
10876 385 shadowtile+=2;
10877 1538 }
10878 else
10879 {
10880 if(misc==0)
10881 {
10882 shadowtile += f2 ? 1 : 0;
10883 }
10884 else if(misc!=1)
10885 {
10886 ++shadowtile;
10887 }
10888 }
10889
10890 1538 yofs+=8;
10891
10892
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1538 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1538 if(!get_bit(quest_rules,qr_ENEMIESZAXIS) && misc==2)
10893 {
10894 yofs+=zc_max(0,zc_min(clk2start-clk2,clk2));
10895 }
10896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1538 times.
1538 if(!shadow_overpit(this))
10897 1538 enemy::drawshadow(dest,translucent);
10898 1538 yofs=tempy;
10899 1651 }
10900
10901 12141 void eTektite::draw(BITMAP *dest)
10902 {
10903 12141 update_enemy_frame();
10904 12141 enemy::draw(dest);
10905 12141 }
10906
10907 6 eItemFairy::eItemFairy(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10908 6 {
10909
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 step=zslongToFix(guysbuf[id&0xFFF].step*100);
10910 3 superman=1;
10911 3 dir=8;
10912 3 hxofs=1000;
10913 3 mainguy=false;
10914 3 count_enemy=false;
10915
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10916 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10917 // al_trace("Enemy txsz:%i\n", txsz);
10918
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
10919
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
10920
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
10921
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
10922
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
10923
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
10924 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10925
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
10926
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10927 {
10928 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
10929 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10930 }
10931
10932
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
10933 3 }
10934
10935 3001 bool eItemFairy::animate(int32_t index)
10936 {
10937
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3001 times.
3001 if(switch_hooked) return enemy::animate(index);
10938
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3001 times.
3001 if(dying)
10939 return Dead(index);
10940
10941 //if(clk>32)
10942 3001 misc=1;
10943 3001 bool w=watch;
10944 3001 watch=false;
10945 3001 variable_walk_8(misc?3:0,0,8,spw_floater);
10946 3001 watch=w;
10947
10948
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2988 times.
3001 if(clk==0)
10949 {
10950 13 removearmos(x,y,ffcactivated);
10951 13 }
10952
10953 3001 return enemy::animate(index);
10954 3001 }
10955
10956 6002 void eItemFairy::draw(BITMAP *dest)
10957 {
10958 //these are here to bypass compiler warnings about unused arguments
10959 6002 dest=dest;
10960 6002 }
10961
10962 ePeahat::ePeahat(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
10963 {
10964 //floater_walk(int32_t rate,int32_t newclk,zfix ms,zfix ss,int32_t s,int32_t p, int32_t g)
10965 floater_walk(misc?rate:0, hrate, zslongToFix(dstep*100),zslongToFix(dstep*10), 10, dmisc16,dmisc17); // 80, 16);
10966 dir=8;
10967 movestatus=1;
10968 clk=0;
10969 step=0;
10970 //nets+720;
10971 SIZEflags = d->SIZEflags;
10972 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
10973 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
10974 // al_trace("Enemy txsz:%i\n", txsz);
10975 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
10976 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
10977 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
10978 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
10979 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
10980 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
10981 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
10982 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
10983 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
10984 {
10985 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
10986 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
10987 }
10988
10989 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
10990 }
10991
10992 bool ePeahat::animate(int32_t index)
10993 {
10994 if(switch_hooked) return enemy::animate(index);
10995 if(fallclk||drownclk) return enemy::animate(index);
10996 if(slide())
10997 {
10998 return false;
10999 }
11000
11001 if(dying)
11002 return Dead(index);
11003
11004 if(clk==0)
11005 {
11006 removearmos(x,y,ffcactivated);
11007 }
11008
11009 if(stunclk==0 && clk>96)
11010 misc=1;
11011
11012 if(!watch)
11013 floater_walk(misc?rate:0, hrate, zslongToFix(dstep*100),zslongToFix(dstep*10), 10, 80, 16);
11014
11015 if(get_bit(quest_rules,qr_ENEMIESZAXIS) && !(isSideViewGravity()))
11016 {
11017 if (moveflags & FLAG_USE_FAKE_Z) fakez=int32_t(step*1.1/((zslongToFix(dstep*10))*1.1));
11018 else z=int32_t(step*1.1/((zslongToFix(dstep*10))*1.1));
11019 }
11020
11021 if(watch && get_bit(quest_rules,qr_PEAHATCLOCKVULN))
11022 superman=0;
11023 else
11024 superman=(movestatus && !get_bit(quest_rules,qr_ENEMIESZAXIS)) ? 1 : 0;
11025 //stunclk=0; //Not sure what was going on here, or what was intended. Why was this set to 0? -Z
11026 if ( FFCore.getQuestHeaderInfo(vZelda) >= 0x250 )
11027 {
11028 if ( stunclk ) --stunclk;
11029 }
11030 else stunclk = 0; //Was probably this way in 2.10 quests. if not, then we never need to clear it. -Z
11031 //Pretty sure this was always an error. -Z ( 14FEB2019 )
11032
11033
11034 if(x<16) dir=right; //this is ugly, but so is moving or creating these guys with scripts.
11035
11036 return enemy::animate(index);
11037 }
11038
11039 void ePeahat::drawshadow(BITMAP *dest, bool translucent)
11040 {
11041 int32_t tempy=yofs;
11042 flip = 0;
11043 shadowtile = wpnsbuf[spr_shadow].tile+posframe;
11044
11045 if(!get_bit(quest_rules,qr_ENEMIESZAXIS))
11046 {
11047 yofs+=8;
11048 yofs+=int32_t(step/zslongToFix(dstep*10));
11049 }
11050 if(!shadow_overpit(this))
11051 enemy::drawshadow(dest,translucent);
11052 yofs=tempy;
11053 }
11054
11055 void ePeahat::draw(BITMAP *dest)
11056 {
11057 update_enemy_frame();
11058 enemy::draw(dest);
11059 }
11060
11061 int32_t ePeahat::takehit(weapon *w)
11062 {
11063 int32_t wpnId = w->id;
11064 int32_t enemyHitWeapon = w->parentitem;
11065
11066 if(dying || clk<0 || hclk>0)
11067 return 0;
11068
11069 if(superman && !(wpnId==wSBomb) // vulnerable to super bombs
11070 // fire boomerang, for nailing peahats
11071 && !(wpnId==wBrang && (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_brang))>0))
11072 return 0;
11073
11074 // Time for a kludge...
11075 int32_t s = superman;
11076 superman = 0;
11077 int32_t ret = enemy::takehit(w);
11078 superman = s;
11079
11080 // Anyway...
11081 if(stunclk == 160)
11082 {
11083 clk2=0;
11084 movestatus=0;
11085 misc=0;
11086 clk=0;
11087 step=0;
11088 }
11089
11090 return ret;
11091 }
11092
11093 // auomatically kill off enemy (for rooms with ringleaders)
11094 void ePeahat::kickbucket()
11095 {
11096 hp=-1000; // don't call death_sfx()
11097 }
11098
11099 8 eLeever::eLeever(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11100 8 {
11101 // if(d->misc1==0) { misc=-1; clk-=16; } //Line of Sight leevers
11102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(dmisc1==0)
11103 {
11104 4 misc=-1; //Line of Sight leevers
11105 4 clk-=16;
11106 4 }
11107 4 clk3 = 0;
11108 //nets+1460;
11109
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 temprule=(get_bit(quest_rules,qr_NEWENEMYTILES)) != 0;
11110 4 submerged = false;
11111 4 SIZEflags = d->SIZEflags;
11112
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11113 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11114 // al_trace("Enemy txsz:%i\n", txsz);
11115
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11116
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11117
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11118
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11119
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11120
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11121 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11122
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11124 {
11125 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11126 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11127 }
11128
11129
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11130 4 }
11131
11132 bool eLeever::isSubmerged() const
11133 {
11134 Z_scripterrlog("misc is: %d\n", misc);
11135 return misc <= 0;
11136
11137 }
11138
11139 721 bool eLeever::animate(int32_t index)
11140 {
11141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 721 times.
721 if(switch_hooked) return enemy::animate(index);
11142
2/4
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 721 times.
721 if(fallclk||drownclk)
11143 {
11144 return enemy::animate(index);
11145 }
11146
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 703 times.
721 if(dying)
11147 18 return Dead(index);
11148
11149
2/2
✓ Branch 0 taken 690 times.
✓ Branch 1 taken 13 times.
703 if(clk==0)
11150 {
11151 13 removearmos(x,y,ffcactivated);
11152 13 }
11153
11154
4/4
✓ Branch 0 taken 489 times.
✓ Branch 1 taken 214 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 474 times.
703 if(clk>=0 && !slide())
11155 {
11156 // switch(d->misc1)
11157
1/2
✓ Branch 0 taken 474 times.
✗ Branch 1 not taken.
474 switch(dmisc1)
11158 {
11159 case 0: //line of sight
11160 case 2:
11161
5/8
✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 186 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
474 switch(misc) //is this leever active
11162 {
11163 case -1: //submerged
11164 {
11165
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
208 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk)) misc = 0;
11166
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 208 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
208 if((dmisc1==2)&&(zc_oldrand()&255))
11167 {
11168 break;
11169 }
11170
11171 208 int32_t active=0;
11172
11173
2/2
✓ Branch 0 taken 1003 times.
✓ Branch 1 taken 208 times.
1211 for(int32_t i=0; i<guys.Count(); i++)
11174 {
11175
4/4
✓ Branch 0 taken 795 times.
✓ Branch 1 taken 208 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 412 times.
1003 if(guys.spr(i)->id==id && (((enemy*)guys.spr(i))->misc>=0))
11176 {
11177 412 ++active;
11178 412 }
11179 1003 }
11180
11181
2/2
✓ Branch 0 taken 205 times.
✓ Branch 1 taken 3 times.
208 if(active<((dmisc1==2)?1:2))
11182 {
11183 3 misc=0; //activate this one
11184 3 clk3=1; //This needs to be set so that it knows that it's being emerged of it's own will and not because it got stunned.
11185 3 }
11186 }
11187 208 break;
11188
11189 case 0:
11190 {
11191
11192
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
5 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk))
11193 {
11194 misc=1;
11195 clk2=0;
11196 }
11197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 else if (clk3<=0)
11198 {
11199 misc = -1;
11200 break;
11201 }
11202 5 int32_t s=0;
11203
11204
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 5 times.
29 for(int32_t i=0; i<guys.Count(); i++)
11205 {
11206
4/4
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 2 times.
24 if(guys.spr(i)->id==id && ((enemy*)guys.spr(i))->misc==1)
11207 {
11208 2 ++s;
11209 2 }
11210 24 }
11211
11212
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if(s>0)
11213 {
11214 2 break;
11215 }
11216
11217 3 int32_t d2=zc_oldrand()&1;
11218
11219
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(HeroDir()>=left)
11220 {
11221 d2+=2;
11222 }
11223
11224
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
3 if(canplace(d2) || canplace(d2^1))
11225 {
11226 3 misc=1;
11227 3 clk2=0;
11228 3 clk=0;
11229 3 }
11230 }
11231 3 break;
11232
11233 case 1:
11234
11235
3/8
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
51 if(++clk2>16||(!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk) && clk2>8)) misc=2;
11236
11237 51 break;
11238
11239 case 2:
11240
11241
3/8
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24 if(++clk2>24||(!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk) && clk2>12)) misc=3;
11242
11243 24 break;
11244
11245 // case 3: if(stunclk) break; if(scored) dir^=1; if(!canmove(dir,false)) misc=4; else move((zfix)(d->step/100.0)); break;
11246 case 3:
11247
11248
3/6
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 186 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 186 times.
186 if(stunclk || frozenclock || watch) break;
11249
11250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 186 times.
186 if(scored) dir^=1;
11251
11252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 186 times.
186 if(!canmove(dir,false)) misc=4;
11253 186 else move(zslongToFix(dstep*100));
11254
11255 186 break;
11256
11257 case 4:
11258 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk)) misc = 2;
11259 if(--clk2<=16)
11260 {
11261 misc=5;
11262 clk=8;
11263 }
11264
11265 break;
11266
11267 case 5:
11268 if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk)) misc = 1;
11269 if(--clk2<=0) misc=((dmisc1==2)?-1:0);
11270
11271 break;
11272 } // switch(misc)
11273
11274 474 break;
11275
11276 default: //random
11277 // step=d->misc3/100.0;
11278
11279 step=zslongToFix(dmisc3*100);
11280 if (get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) || (!watch && !stunclk)) ++clk2;
11281 else if (!get_bit(quest_rules, qr_LEEVERS_DONT_OBEY_STUN) && (watch || stunclk))
11282 {
11283 if (clk2 < 48) clk2+=2;
11284 if (clk2 >= 300) clk2-=2;
11285 }
11286
11287 if(clk2<32) misc=1;
11288 else if(clk2<48) misc=2;
11289 else if(clk2<300)
11290 {
11291 /*if(misc==2 && (int32_t)(dmisc3*0.48)%8)
11292 {
11293 fix_coords();
11294 }*/
11295 misc=3;
11296 step = zslongToFix(dstep*100);
11297 }
11298 else if(clk2<316) misc=2;
11299 else if(clk2<412) misc=1;
11300 else if(clk2<540)
11301 {
11302 misc=0;
11303 step=0;
11304 }
11305 else clk2=0;
11306
11307 if(clk2==48) clk=0;
11308
11309 // variable_walk(d->rate, d->homing, 0);
11310 variable_walk(rate, homing, 0);
11311 } // switch(dmisc1)
11312 474 }
11313
11314 703 hxofs=(misc>=2)?0:1000;
11315 703 return enemy::animate(index);
11316 721 }
11317
11318 4 bool eLeever::canplace(int32_t d2)
11319 {
11320 4 int32_t nx=HeroX();
11321 4 int32_t ny=HeroY();
11322
11323
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(d2<left) ny&=0xF0;
11324 else nx&=0xF0;
11325
11326
2/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
4 switch(d2)
11327 {
11328 // case up: ny-=((d->misc1==0)?32:48); break;
11329 // case down: ny+=((d->misc1==0)?32:48); if(ny-HeroY()<32) ny+=((d->misc1==0)?16:0); break;
11330 // case left: nx-=((d->misc1==0)?32:48); break;
11331 // case right: nx+=((d->misc1==0)?32:48); if(nx-HeroX()<32) nx+=((d->misc1==0)?16:0); break;
11332 case up:
11333
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 ny-=((dmisc1==0||dmisc1==2)?32:48);
11334 1 break;
11335
11336 case down:
11337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 ny+=((dmisc1==0||dmisc1==2)?32:48);
11338
11339
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if(ny-HeroY()<32) ny+=((dmisc1==0||dmisc1==2)?16:0);
11340
11341 3 break;
11342
11343 case left:
11344 nx-=((dmisc1==0||dmisc1==2)?32:48);
11345 break;
11346
11347 case right:
11348 nx+=((dmisc1==0||dmisc1==2)?32:48);
11349
11350 if(nx-HeroX()<32) nx+=((dmisc1==0||dmisc1==2)?16:0);
11351
11352 break;
11353 }
11354
11355
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
4 if(m_walkflag(nx,ny,spw_halfstep, dir)||m_walkflag(nx,ny-8,spw_halfstep, dir)) /*none*/
11356 1 return false;
11357
11358
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(d2>=left)
11359 if(m_walkflag(HeroX(),HeroY(),spw_halfstep, dir)||m_walkflag(HeroX(),HeroY()-8,spw_halfstep, dir)) /*none*/
11360 return false;
11361
11362 3 x=nx;
11363 3 y=ny;
11364 3 dir=d2^1;
11365 3 return true;
11366 4 }
11367
11368 721 void eLeever::draw(BITMAP *dest)
11369 {
11370 // cs=d->cset;
11371 721 cs=dcset;
11372 721 update_enemy_frame();
11373
2/4
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 721 times.
721 if(!fallclk&&!drownclk)
11374 {
11375
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 427 times.
721 switch(misc)
11376 {
11377 case -1:
11378 case 0:
11379 427 return;
11380 }
11381 294 }
11382
11383 294 enemy::draw(dest);
11384 721 }
11385
11386 32 eWallM::eWallM(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11387 32 {
11388 //zprint2("eWallM::eWallM\n");
11389 16 hashero=false;
11390 //nets+1000;
11391 16 SIZEflags = d->SIZEflags;
11392
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11393 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11394 // al_trace("Enemy txsz:%i\n", txsz);
11395
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11396
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11397
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11398
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11399
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11400
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11401 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11402
1/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11404 {
11405 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11406 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11407 }
11408
11409
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11410 16 }
11411
11412 8285 bool eWallM::animate(int32_t index)
11413 {
11414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8285 times.
8285 if(switch_hooked) return enemy::animate(index);
11415
2/4
✓ Branch 0 taken 8285 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8285 times.
8285 if(fallclk||drownclk)
11416 {
11417 return enemy::animate(index);
11418 }
11419
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 8123 times.
8285 if(dying)
11420 162 return Dead(index);
11421
11422
2/2
✓ Branch 0 taken 7670 times.
✓ Branch 1 taken 453 times.
8123 if(clk==0)
11423 {
11424 453 removearmos(x,y,ffcactivated);
11425 453 }
11426
11427 8123 hxofs=1000;
11428
2/2
✓ Branch 0 taken 3051 times.
✓ Branch 1 taken 5072 times.
8123 if(misc==0) //inside wall, ready to spawn?
11429 {
11430 //zprint2("Wallmaster is ready to spawn, clk is: %d\n",clk);
11431 //zprint2("frame is: %d\n",frame);
11432 //zprint2("wallm_load_clk is: %d\n",wallm_load_clk);
11433
4/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3378 times.
✓ Branch 2 taken 267 times.
✓ Branch 3 taken 1427 times.
5072 if(frame-wallm_load_clk>80 && clk>=0)
11434 {
11435 //zprint2("getting wall\n");
11436 1427 int32_t wall=hero_on_wall();
11437 //zprint2("Wallmaster wall is %d\n",wall);
11438 1427 int32_t wallm_cnt=0;
11439
11440
2/2
✓ Branch 0 taken 11411 times.
✓ Branch 1 taken 1427 times.
12838 for(int32_t i=0; i<guys.Count(); i++)
11441
2/2
✓ Branch 0 taken 899 times.
✓ Branch 1 taken 10512 times.
21923 if(((enemy*)guys.spr(i))->family==eeWALLM)
11442 {
11443 10512 int32_t m=((enemy*)guys.spr(i))->misc;
11444
11445
4/4
✓ Branch 0 taken 1764 times.
✓ Branch 1 taken 8748 times.
✓ Branch 2 taken 1762 times.
✓ Branch 3 taken 2 times.
10512 if(m && ((enemy*)guys.spr(i))->clk3==(wall^1))
11446 {
11447 2 ++wallm_cnt;
11448 2 }
11449 10512 }
11450
11451
2/2
✓ Branch 0 taken 1414 times.
✓ Branch 1 taken 13 times.
1427 if(wall>0)
11452 {
11453 13 --wall;
11454 13 misc=1; //emerging from the wall?
11455 //zprint2("Wallmaster is emerging\n");
11456 13 clk2=0;
11457 13 clk3=wall^1;
11458 13 wallm_load_clk=frame;
11459
11460
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 9 times.
13 if(wall<=down)
11461 {
11462
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if(HeroDir()==left)
11463 1 dir=right;
11464 else
11465 3 dir=left;
11466 4 }
11467 else
11468 {
11469
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if(HeroDir()==up)
11470 2 dir=down;
11471 else
11472 7 dir=up;
11473 }
11474
11475
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 5 times.
13 switch(wall)
11476 {
11477 case up:
11478 3 y=0;
11479 3 break;
11480
11481 case down:
11482 1 y=160;
11483 1 break;
11484
11485 case left:
11486 4 x=0;
11487 4 break;
11488
11489 case right:
11490 5 x=240;
11491 5 break;
11492 }
11493
11494 //zprint2("Wallmaster (p1) x is %d\n",x);
11495 //zprint2("Wallmaster (p1) y is %d\n",y);
11496
11497
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
13 switch(dir)
11498 {
11499 case up:
11500 7 y=(HeroY()+48-(wallm_cnt&1)*12);
11501 7 flip=wall&1;
11502 7 break;
11503
11504 case down:
11505 2 y=(HeroY()-48+(wallm_cnt&1)*12);
11506 2 flip=((wall&1)^1)+2;
11507 2 break;
11508
11509 case left:
11510 3 x=(HeroX()+48-(wallm_cnt&1)*12);
11511 3 flip=(wall==up?2:0)+1;
11512 3 break;
11513
11514 case right:
11515 1 x=(HeroX()-48+(wallm_cnt&1)*12);
11516 1 flip=(wall==up?2:0);
11517 1 break;
11518 }
11519
11520 //zprint2("Wallmaster (p2) x is %d\n",x);
11521 //zprint2("Wallmaster (p2) y is %d\n",y);
11522 13 }
11523 1427 }
11524 5072 }
11525 else
11526 3051 wallm_crawl();
11527
11528 8123 return enemy::animate(index);
11529 8285 }
11530
11531 3051 void eWallM::wallm_crawl()
11532 {
11533 3051 bool w=watch;
11534 3051 hxofs=0;
11535
11536
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 3035 times.
3051 if(slide())
11537 {
11538 16 return;
11539 }
11540
11541 // if(dying || watch || (!hashero && stunclk))
11542
5/8
✓ Branch 0 taken 3035 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3035 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1859 times.
✓ Branch 5 taken 1176 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1859 times.
3035 if(dying || (!hashero && ( stunclk || frozenclock )))
11543 {
11544 1176 return;
11545 }
11546
11547 1859 watch=false;
11548 1859 ++clk2;
11549 // Misc1: slightly different movement
11550 //zprint2("wallmaster crawl\n");
11551 //zprint2("wallmaster tmpdstep is %d\n",tmpdstep);
11552 1859 float tmpmisc3 = ((40.0/(int32_t)dstep)*40);
11553
11554 //int32_t tmpmisc = int32_t((40.0/dstep)*40);
11555 //zprint2("wallmaster crawl tmpmisc is: %d\n", tmpmisc);
11556 //zprint2("wallmaster crawl tmpmisc4 is: %d\n", tmpmisc4);
11557
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1859 times.
1859 misc=(clk2/(dmisc1==1?40:(int32_t)tmpmisc3))+1;
11558 //zprint2("wallmaster crawl misc is: %d\n", misc);
11559
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 1859 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1859 if(w&&misc>=3&&misc<=5)
11560 {
11561 --clk2;
11562 }
11563
11564
4/4
✓ Branch 0 taken 709 times.
✓ Branch 1 taken 988 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 2 times.
1859 switch(misc)
11565 {
11566 case 1:
11567 case 2:
11568 988 zc_swap(dir,clk3);
11569 988 move(step);
11570 988 zc_swap(dir,clk3);
11571 988 break;
11572
11573 case 3:
11574 case 4:
11575 case 5:
11576
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 709 times.
709 if(w)
11577 {
11578 watch=w;
11579 return;
11580 }
11581
11582 709 move(step);
11583 709 break;
11584
11585 case 6:
11586 case 7:
11587 160 zc_swap(dir,clk3);
11588 160 dir^=1;
11589 160 move(step);
11590 160 dir^=1;
11591 160 zc_swap(dir,clk3);
11592 160 break;
11593
11594 default:
11595 2 misc=0;
11596 2 break;
11597 }
11598
11599 1859 watch=w;
11600 3051 }
11601
11602 void eWallM::grabhero()
11603 {
11604 hashero=true;
11605 superman=1;
11606 }
11607
11608 8285 void eWallM::draw(BITMAP *dest)
11609 {
11610 8285 dummy_bool[1]=hashero;
11611 8285 update_enemy_frame();
11612
11613
4/6
✓ Branch 0 taken 5072 times.
✓ Branch 1 taken 3213 times.
✓ Branch 2 taken 5072 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5072 times.
8285 if(misc>0 || fallclk||drownclk)
11614 {
11615 3213 masked_draw(dest,16,playing_field_offset+16,224,144);
11616 3213 }
11617
11618 // enemy::draw(dest);
11619 // tile = clk&8 ? 128:129;
11620 8285 }
11621
11622 bool eWallM::isSubmerged() const
11623 {
11624 return ( !misc );
11625 }
11626
11627 eTrap::eTrap(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11628 {
11629 ox=x; //original x
11630 oy=y; //original y
11631 if(get_bit(quest_rules,qr_TRAPPOSFIX))
11632 {
11633 yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
11634 }
11635
11636 mainguy=false;
11637 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
11638 //nets+420;
11639 dummy_int[1]=0;
11640 SIZEflags = d->SIZEflags;
11641 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11642 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11643 // al_trace("Enemy txsz:%i\n", txsz);
11644 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11645 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11646 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11647 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11648 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11649 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11650 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11651 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11652 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11653 {
11654 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11655 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11656 }
11657
11658 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
11659 }
11660
11661 bool eTrap::animate(int32_t index)
11662 {
11663 if(switch_hooked) return enemy::animate(index);
11664 if(fallclk||drownclk) return enemy::animate(index);
11665 if(clk<0)
11666 return enemy::animate(index);
11667
11668 if(clk==0)
11669 {
11670 removearmos(x,y,ffcactivated);
11671 }
11672
11673 if(misc==0) // waiting
11674 {
11675 ox = x;
11676 oy = y;
11677 double _MSVC2022_tmp1, _MSVC2022_tmp2;
11678 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
11679
11680 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
11681 {
11682 dir=down;
11683 }
11684 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
11685 {
11686 dir=right;
11687 }
11688 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
11689 {
11690 dir=up;
11691 }
11692 else
11693 {
11694 dir=left;
11695 }
11696
11697 int32_t d2=lined_up(15,true);
11698
11699 if(((d2<left || d2 > right) && (dmisc1==1)) ||
11700 ((d2>down) && (dmisc1==2)) ||
11701 ((d2>right) && (!dmisc1)) ||
11702 ((d2<l_up) && (dmisc1==4)) ||
11703 ((d2!=r_up) && (d2!=l_down) && (dmisc1==6)) ||
11704 ((d2!=l_up) && (d2!=r_down) && (dmisc1==8)))
11705 {
11706 d2=-1;
11707 }
11708
11709 if(d2!=-1 && trapmove(d2))
11710 {
11711 dir=d2;
11712 misc=1;
11713 clk2=(dir==down)?3:0;
11714 }
11715 }
11716
11717 if(misc==1) // charging
11718 {
11719 clk2=(clk2+1)&3;
11720 step=(clk2==3)?1:2;
11721
11722 if(!trapmove(dir) || clip())
11723 {
11724 misc=2;
11725
11726 if(dir<l_up)
11727 {
11728 dir=dir^1;
11729 }
11730 else
11731 {
11732 dir=dir^3;
11733 }
11734 }
11735 else
11736 {
11737 sprite::move(step);
11738 }
11739 }
11740
11741 if(misc==2) // retreating
11742 {
11743 step=(++clk2&1)?1:0;
11744
11745 switch(dir)
11746 {
11747 case up:
11748 if(int32_t(y)<=oy) goto trap_rest;
11749 else sprite::move(step);
11750
11751 break;
11752
11753 case left:
11754 if(int32_t(x)<=ox) goto trap_rest;
11755 else sprite::move(step);
11756
11757 break;
11758
11759 case down:
11760 if(int32_t(y)>=oy) goto trap_rest;
11761 else sprite::move(step);
11762
11763 break;
11764
11765 case right:
11766 if(int32_t(x)>=ox) goto trap_rest;
11767 else sprite::move(step);
11768
11769 break;
11770
11771 case l_up:
11772 if(int32_t(x)<=ox && int32_t(y)<=oy) goto trap_rest;
11773 else sprite::move(step);
11774
11775 break;
11776
11777 case r_up:
11778 if(int32_t(x)>=ox && int32_t(y)<=oy) goto trap_rest;
11779 else sprite::move(step);
11780
11781 break;
11782
11783 case l_down:
11784 if(int32_t(x)<=ox && int32_t(y)>=oy) goto trap_rest;
11785 else sprite::move(step);
11786
11787 break;
11788
11789 case r_down:
11790 if(int32_t(x)>=ox && int32_t(y)>=oy) goto trap_rest;
11791 else sprite::move(step);
11792
11793 break;
11794 trap_rest:
11795 {
11796 x=ox;
11797 y=oy;
11798 misc=0;
11799 }
11800 }
11801 }
11802
11803 return enemy::animate(index);
11804 }
11805
11806 bool eTrap::trapmove(int32_t ndir)
11807 {
11808 if(get_bit(quest_rules,qr_MEANTRAPS))
11809 {
11810 if(tmpscr->flags2&fFLOATTRAPS)
11811 return canmove(ndir,(zfix)1,spw_floater, 0, 0, 15, 15,false);
11812
11813 return canmove(ndir,(zfix)1,spw_water, 0, 0, 15, 15,false);
11814 }
11815
11816 if(oy==80 && !(ndir==left || ndir == right))
11817 return false;
11818
11819 if(ox==128 && !(ndir==up || ndir==down))
11820 return false;
11821
11822 if(oy<80 && ndir==up)
11823 return false;
11824
11825 if(oy>80 && ndir==down)
11826 return false;
11827
11828 if(ox<128 && ndir==left)
11829 return false;
11830
11831 if(ox>128 && ndir==right)
11832 return false;
11833
11834 if(ox<128 && oy<80 && ndir==l_up)
11835 return false;
11836
11837 if(ox<128 && oy>80 && ndir==l_down)
11838 return false;
11839
11840 if(ox>128 && oy<80 && ndir==r_up)
11841 return false;
11842
11843 if(ox>128 && oy>80 && ndir==r_down)
11844 return false;
11845
11846 return true;
11847 }
11848
11849 bool eTrap::clip()
11850 {
11851 if(get_bit(quest_rules,qr_MEANPLACEDTRAPS))
11852 {
11853 switch(dir)
11854 {
11855 case up:
11856 if(y<=0) return true;
11857
11858 break;
11859
11860 case down:
11861 if(y>=160) return true;
11862
11863 break;
11864
11865 case left:
11866 if(x<=0) return true;
11867
11868 break;
11869
11870 case right:
11871 if(x>=240) return true;
11872
11873 break;
11874
11875 case l_up:
11876 if(y<=0||x<=0) return true;
11877
11878 break;
11879
11880 case l_down:
11881 if(y>=160||x<=0) return true;
11882
11883 break;
11884
11885 case r_up:
11886 if(y<=0||x>=240) return true;
11887
11888 break;
11889
11890 case r_down:
11891 if(y>=160||x>=240) return true;
11892
11893 break;
11894 }
11895
11896 return false;
11897 }
11898 else
11899 {
11900 switch(dir)
11901 {
11902 case up:
11903 if(oy>80 && y<=86) return true;
11904
11905 break;
11906
11907 case down:
11908 if(oy<80 && y>=80) return true;
11909
11910 break;
11911
11912 case left:
11913 if(ox>128 && x<=124) return true;
11914
11915 break;
11916
11917 case right:
11918 if(ox<120 && x>=116) return true;
11919
11920 break;
11921
11922 case l_up:
11923 if(oy>80 && y<=86 && ox>128 && x<=124) return true;
11924
11925 break;
11926
11927 case l_down:
11928 if(oy<80 && y>=80 && ox>128 && x<=124) return true;
11929
11930 break;
11931
11932 case r_up:
11933 if(oy>80 && y<=86 && ox<120 && x>=116) return true;
11934
11935 break;
11936
11937 case r_down:
11938 if(oy<80 && y>=80 && ox<120 && x>=116) return true;
11939
11940 break;
11941 }
11942
11943 return false;
11944 }
11945 }
11946
11947 void eTrap::draw(BITMAP *dest)
11948 {
11949 update_enemy_frame();
11950 enemy::draw(dest);
11951 }
11952
11953 int32_t eTrap::takehit(weapon*)
11954 {
11955 return 0;
11956 }
11957
11958 eTrap2::eTrap2(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
11959 {
11960 lasthit=-1;
11961 lasthitclk=0;
11962 mainguy=false;
11963 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
11964 step=2;
11965 if(dmisc1==1 || (dmisc1==0 && zc_oldrand()&2))
11966 {
11967 dir=(x<=112)?right:left;
11968 }
11969 else
11970 {
11971 dir=(y<=72)?down:up;
11972 }
11973
11974 if(get_bit(quest_rules,qr_TRAPPOSFIX))
11975 {
11976 yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
11977 }
11978
11979 //nets+((id==eTRAP_LR)?540:520);
11980 dummy_int[1]=0;
11981 SIZEflags = d->SIZEflags;
11982 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
11983 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
11984 // al_trace("Enemy txsz:%i\n", txsz);
11985 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
11986 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
11987 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
11988 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
11989 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
11990 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
11991 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
11992 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
11993 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
11994 {
11995 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
11996 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
11997 }
11998
11999 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
12000 }
12001
12002 bool eTrap2::animate(int32_t index)
12003 {
12004 if(switch_hooked) return enemy::animate(index);
12005 if(fallclk||drownclk) return enemy::animate(index);
12006 if(clk<0)
12007 return enemy::animate(index);
12008
12009 if(clk==0)
12010 {
12011 removearmos(x,y,ffcactivated);
12012 }
12013
12014 if(!get_bit(quest_rules,qr_PHANTOMPLACEDTRAPS))
12015 {
12016 if(lasthitclk>0)
12017 {
12018 --lasthitclk;
12019 }
12020 else
12021 {
12022 lasthit=-1;
12023 }
12024
12025 bool hitenemy=false;
12026
12027 for(int32_t j=0; j<guys.Count(); j++)
12028 {
12029 if((j!=index) && (lasthit!=j))
12030 {
12031 if(hit(guys.spr(j)))
12032 {
12033 lasthit=j;
12034 lasthitclk=10;
12035 hitenemy=true;
12036 guys.spr(j)->lasthit=index;
12037 guys.spr(j)->lasthitclk=10;
12038 // guys.spr(j)->dir=guys.spr(j)->dir^1;
12039 }
12040 }
12041 }
12042
12043 if(!trapmove(dir) || clip() || hitenemy)
12044 {
12045 if(!trapmove(dir) || clip())
12046 {
12047 lasthit=-1;
12048 lasthitclk=0;
12049 }
12050
12051 if(get_bit(quest_rules,qr_MORESOUNDS))
12052 sfx(WAV_ZN1TAP,pan(int32_t(x)));
12053
12054 dir=dir^1;
12055 }
12056
12057 sprite::move(step);
12058 }
12059 else
12060 {
12061 if(!trapmove(dir) || clip())
12062 {
12063 if(get_bit(quest_rules,qr_MORESOUNDS))
12064 sfx(WAV_ZN1TAP,pan(int32_t(x)));
12065
12066 dir=dir^1;
12067 }
12068
12069 sprite::move(step);
12070 }
12071
12072 return enemy::animate(index);
12073 }
12074
12075 bool eTrap2::trapmove(int32_t ndir)
12076 {
12077 if(tmpscr->flags2&fFLOATTRAPS)
12078 return canmove(ndir,(zfix)1,spw_floater, 0, 0, 15, 15,false);
12079
12080 return canmove(ndir,(zfix)1,spw_water, 0, 0, 15, 15,false);
12081 }
12082
12083 bool eTrap2::clip()
12084 {
12085 switch(dir)
12086 {
12087 case up:
12088 if(y<=0) return true;
12089
12090 break;
12091
12092 case down:
12093 if(y>=160) return true;
12094
12095 break;
12096
12097 case left:
12098 if(x<=0) return true;
12099
12100 break;
12101
12102 case right:
12103 if(x>=240) return true;
12104
12105 break;
12106 }
12107
12108 return false;
12109 }
12110
12111 void eTrap2::draw(BITMAP *dest)
12112 {
12113 update_enemy_frame();
12114 enemy::draw(dest);
12115 }
12116
12117 int32_t eTrap2::takehit(weapon*)
12118 {
12119 return 0;
12120 }
12121
12122 eRock::eRock(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12123 {
12124 //do not show "enemy appering" anim -DD
12125 clk=0;
12126 mainguy=false;
12127 clk2=-14;
12128 //Enemy Editor Size Tab
12129 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12130 else hxofs = -2;
12131 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12132 else hyofs = -2;
12133 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
12134 else hxsz = 20;
12135 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
12136 else hysz=20;
12137
12138 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12139 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12140 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
12141 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
12142 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12143 {
12144 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12145 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12146 }
12147
12148 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
12149 //nets+1640;
12150 }
12151
12152 bool eRock::animate(int32_t index)
12153 {
12154 if(switch_hooked) return enemy::animate(index);
12155 if(fallclk||drownclk) return enemy::animate(index);
12156 if(dying)
12157 return Dead(index);
12158
12159 if(clk==0)
12160 {
12161 removearmos(x,y,ffcactivated);
12162 }
12163
12164 if(++clk2==0) // start it
12165 {
12166 x=zc_oldrand()&0xF0;
12167 y=0;
12168 clk3=0;
12169 clk2=zc_oldrand()&15;
12170 }
12171
12172 if(clk2>16) // move it
12173 {
12174 if(clk3<=0) // start bounce
12175 {
12176 dir=zc_oldrand()&1;
12177
12178 if(x<32) dir=1;
12179
12180 if(x>208) dir=0;
12181 }
12182
12183 if(clk3<13+16)
12184 {
12185 x += dir ? 1 : -1; //right, left
12186 dummy_int[1]=dir;
12187
12188 if(clk3<2)
12189 {
12190 y-=2; //up
12191 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12192 }
12193 else if(clk3<5)
12194 {
12195 y--; //up
12196 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12197 }
12198 else if(clk3<8)
12199 {
12200 dummy_int[2]=(dummy_int[1]==1)?right:left;
12201 }
12202 else if(clk3<11)
12203 {
12204 y++; //down
12205 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12206 }
12207 else
12208 {
12209 y+=2; //down
12210 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12211 }
12212
12213 ++clk3;
12214 }
12215 else if(y<176)
12216 clk3=0; // next bounce
12217 else
12218 clk2 = -(zc_oldrand()&63); // back to top
12219 }
12220
12221 return enemy::animate(index);
12222 }
12223
12224 void eRock::drawshadow(BITMAP *dest, bool translucent)
12225 {
12226 if(clk2>=0)
12227 {
12228 int32_t tempy=yofs;
12229 flip = 0;
12230 int32_t fdiv = frate/4;
12231 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
12232 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
12233 efrate:((clk>=(frate>>1))?1:0);
12234 shadowtile = wpnsbuf[spr_shadow].tile+f2;
12235
12236 yofs+=8;
12237 yofs+=zc_max(0,zc_min(29-clk3,clk3));
12238 if(!shadow_overpit(this))
12239 enemy::drawshadow(dest, translucent);
12240 yofs=tempy;
12241 }
12242 }
12243
12244 void eRock::draw(BITMAP *dest)
12245 {
12246 if(clk2>=0 || fallclk||drownclk)
12247 {
12248 int32_t tempdir=dir;
12249 dir=dummy_int[2];
12250 update_enemy_frame();
12251 enemy::draw(dest);
12252 dir=tempdir;
12253 }
12254 }
12255
12256 int32_t eRock::takehit(weapon*)
12257 {
12258 return 0;
12259 }
12260
12261 eBoulder::eBoulder(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12262 {
12263 clk=0;
12264 mainguy=false;
12265 clk2=-14;
12266 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12267 else hxofs= -10;
12268 if ( (d->SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12269 else hyofs=-10;
12270 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
12271 else hxsz=36;
12272 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
12273 else hysz=36;
12274 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
12275 else hzsz=16; //can't be jumped
12276
12277 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12278 if ( ((d->SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12279 if ( ((d->SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
12280 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
12281 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12282 {
12283 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12284 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12285 }
12286
12287 if ( (d->SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
12288 //nets+1680;
12289 }
12290
12291 bool eBoulder::animate(int32_t index)
12292 {
12293 if(switch_hooked) return enemy::animate(index);
12294 if(fallclk||drownclk) return enemy::animate(index);
12295 if(dying)
12296 return Dead(index);
12297
12298 if(clk==0)
12299 {
12300 removearmos(x,y,ffcactivated);
12301 }
12302
12303 zfix *vert;
12304 vert = (moveflags & FLAG_USE_FAKE_Z) ? &fakez : get_bit(quest_rules,qr_ENEMIESZAXIS) ? &z : &y;
12305
12306 if(++clk2==0) // start it
12307 {
12308 x=zc_oldrand()&0xF0;
12309 y=-32;
12310 clk3=0;
12311 clk2=zc_oldrand()&15;
12312 }
12313
12314 if(clk2>16) // move it
12315 {
12316 if(clk3<=0) // start bounce
12317 {
12318 dir=zc_oldrand()&1;
12319
12320 if(x<32) dir=1;
12321
12322 if(x>208) dir=0;
12323 }
12324
12325 if(clk3<13+16)
12326 {
12327 x += dir ? 1 : -1; //right, left
12328 dummy_int[1]=dir;
12329
12330 if(clk3<2)
12331 {
12332 y-=2; //up
12333 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12334 }
12335 else if(clk3<5)
12336 {
12337 y--; //up
12338 dummy_int[2]=(dummy_int[1]==1)?r_up:l_up;
12339 }
12340 else if(clk3<8)
12341 {
12342 dummy_int[2]=(dummy_int[1]==1)?right:left;
12343 }
12344 else if(clk3<11)
12345 {
12346 y++; //down
12347 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12348 }
12349 else
12350 {
12351 y+=2; //down
12352 dummy_int[2]=(dummy_int[1]==1)?r_down:l_down;
12353 }
12354
12355 ++clk3;
12356 }
12357 else if(y<176)
12358 clk3=0; // next bounce
12359 else
12360 clk2 = -(zc_oldrand()&63); // back to top
12361 }
12362
12363 return enemy::animate(index);
12364 }
12365
12366 void eBoulder::drawshadow(BITMAP *dest, bool translucent)
12367 {
12368 if(clk2>=0)
12369 {
12370 int32_t tempy=yofs;
12371 flip = 0;
12372 int32_t f2=((clk<<2)/frate)<<1;
12373 shadowtile = wpnsbuf[spr_shadow].tile+f2;
12374 yofs+=zc_max(0,zc_min(29-clk3,clk3));
12375
12376 yofs+=8;
12377 xofs-=8;
12378 if(!shadow_overpit(this))
12379 enemy::drawshadow(dest, translucent);
12380 xofs+=16;
12381 ++shadowtile;
12382 if(!shadow_overpit(this))
12383 enemy::drawshadow(dest, translucent);
12384 yofs+=16;
12385 shadowtile+=20;
12386 if(!shadow_overpit(this))
12387 enemy::drawshadow(dest, translucent);
12388 xofs-=16;
12389 --shadowtile;
12390 if(!shadow_overpit(this))
12391 enemy::drawshadow(dest, translucent);
12392 xofs+=8;
12393 yofs=tempy;
12394 }
12395 }
12396
12397 void eBoulder::draw(BITMAP *dest)
12398 {
12399 if(clk2>=0 || fallclk||drownclk)
12400 {
12401 int32_t tempdir=dir;
12402 dir=dummy_int[2];
12403 update_enemy_frame();
12404 dir=tempdir;
12405 xofs-=8;
12406 yofs-=8;
12407 drawblock(dest,15);
12408 xofs+=8;
12409 yofs+=8;
12410 // enemy::draw(dest);
12411 }
12412 }
12413
12414 int32_t eBoulder::takehit(weapon*)
12415 {
12416 return 0;
12417 }
12418
12419 12 eProjectile::eProjectile(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk),
12420
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 minRange(get_bit(quest_rules, qr_BROKENSTATUES) ? 0 : Clk)
12421 12 {
12422 /* fixing
12423 hp=1;
12424 */
12425 6 mainguy=false;
12426
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12427 6 hclk=clk; // the "no fire" range
12428 6 clk=0;
12429 6 clk3=96;
12430 6 timer=0;
12431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(o_tile==0)
12432 {
12433 6 superman=1;
12434 6 hxofs=1000;
12435 6 }
12436 6 SIZEflags = d->SIZEflags;
12437
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12438 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12439 // al_trace("Enemy txsz:%i\n", txsz);
12440
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12441
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12442
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12443
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12444
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12445
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12446 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12447
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12449 {
12450 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12451 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12452 }
12453
12454
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12455 6 }
12456
12457 412 bool eProjectile::animate(int32_t index)
12458 {
12459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 412 times.
412 if(switch_hooked) return enemy::animate(index);
12460
2/4
✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 412 times.
412 if(fallclk||drownclk) return enemy::animate(index);
12461
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 6 times.
412 if(clk==0)
12462 {
12463 6 removearmos(x,y,ffcactivated);
12464 6 }
12465
12466 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12467 412 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12468
12469
3/4
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 246 times.
✓ Branch 2 taken 166 times.
✗ Branch 3 not taken.
412 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
12470 {
12471 dir=down;
12472 }
12473
4/4
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 166 times.
✓ Branch 3 taken 80 times.
412 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
12474 {
12475 80 dir=right;
12476 80 }
12477
3/4
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 166 times.
✓ Branch 2 taken 166 times.
✗ Branch 3 not taken.
332 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/4)))
12478 {
12479 dir=up;
12480 }
12481 else
12482 {
12483 332 dir=left;
12484 }
12485
12486
3/4
✓ Branch 0 taken 412 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 313 times.
412 if(!stunclk && ++clk3>80)
12487 {
12488
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 313 times.
313 if(dmisc1==9) // Breath type
12489 {
12490 if(timer==0)
12491 {
12492 unsigned r=zc_oldrand();
12493
12494 if(!(r&63))
12495 {
12496 timer=zc_oldrand()%50+50;
12497 }
12498 }
12499
12500 if(timer>0)
12501 {
12502 if(timer%4==0)
12503 {
12504 FireBreath(false);
12505 }
12506
12507 if(--timer==0)
12508 {
12509 clk3=0;
12510 }
12511 }
12512 }
12513
12514 else // Not breath type
12515 {
12516 313 unsigned r=zc_oldrand();
12517
12518
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 310 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
313 if(!(r&63) && !HeroInRange(minRange))
12519 {
12520 3 FireWeapon();
12521
12522
1/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 if(get_bit(quest_rules, qr_BROKENSTATUES)==0 &&
12523
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3 ((wpn==ewFireball || wpn==ewFireball2) || dmisc1==e1tNORMAL))
12524 {
12525
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(!((r>>7)&15))
12526 {
12527 x-=4;
12528 FireWeapon();
12529 x+=4;
12530 }
12531 3 }
12532
12533 3 clk3=0;
12534 3 }
12535 }
12536 313 }
12537
12538 412 return enemy::animate(index);
12539 412 }
12540
12541 412 void eProjectile::draw(BITMAP *dest)
12542 {
12543 412 update_enemy_frame();
12544 412 enemy::draw(dest);
12545 412 }
12546
12547 eTrigger::eTrigger(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12548 {
12549 hxofs=1000;
12550 }
12551
12552 void eTrigger::draw(BITMAP *dest)
12553 {
12554 update_enemy_frame();
12555 enemy::draw(dest);
12556 }
12557
12558 void eTrigger::death_sfx()
12559 {
12560 //silent death
12561 }
12562
12563 eNPC::eNPC(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12564 {
12565 o_tile+=wpnsbuf[iwNPCs].tile;
12566 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12567 SIZEflags = d->SIZEflags;
12568 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12569 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12570 // al_trace("Enemy txsz:%i\n", txsz);
12571 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12572 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12573 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12574 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12575 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12576 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12577 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12578 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12579 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12580 {
12581 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12582 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12583 }
12584
12585 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12586 }
12587
12588 bool eNPC::animate(int32_t index)
12589 {
12590 if(switch_hooked) return enemy::animate(index);
12591 if(dying)
12592 return Dead(index);
12593
12594 if(clk==0)
12595 {
12596 removearmos(x,y,ffcactivated);
12597 }
12598
12599 switch(dmisc2)
12600 {
12601 case 0:
12602 {
12603 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12604 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12605
12606 if((ddir<=(((-1)*PI)/4))&&(ddir>(((-3)*PI)/4)))
12607 {
12608 dir=down;
12609 }
12610
12611 else if((ddir<=(((1)*PI)/4))&&(ddir>(((-1)*PI)/4)))
12612 {
12613 dir=right;
12614 }
12615 else if((ddir<=(((3)*PI)/4))&&(ddir>(((1)*PI)/8)))
12616 {
12617 dir=up;
12618 }
12619 else
12620 {
12621 dir=left;
12622 }
12623 }
12624 break;
12625
12626 case 1:
12627 halting_walk(rate, homing, 0, hrate, 48);
12628
12629 if(clk2==1 && (misc < dmisc1) && !(zc_oldrand()&15))
12630 {
12631 newdir(rate, homing, 0);
12632 clk2=48;
12633 ++misc;
12634 }
12635
12636 if(clk2==0)
12637 misc=0;
12638
12639 break;
12640 }
12641
12642 return enemy::animate(index);
12643 }
12644
12645 void eNPC::draw(BITMAP *dest)
12646 {
12647 update_enemy_frame();
12648 enemy::draw(dest);
12649 }
12650
12651 int32_t eNPC::takehit(weapon*)
12652 {
12653 return 0;
12654 }
12655
12656 eSpinTile::eSpinTile(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12657 {
12658 if(clk>0) // clk>0 when created by a Spinning Tile combo
12659 {
12660 o_tile=clk;
12661 cs=id>>12;
12662 }
12663
12664 id=id&0xFFF;
12665 clk=0;
12666 step=0;
12667 mainguy=false;
12668 SIZEflags = d->SIZEflags;
12669 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12670 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12671 // al_trace("Enemy txsz:%i\n", txsz);
12672 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12673 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12674 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12675 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12676 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12677 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12678 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12679 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12680 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12681 {
12682 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12683 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12684 }
12685
12686 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12687 }
12688
12689 void eSpinTile::facehero()
12690 {
12691 if(Hero.x-x==0)
12692 {
12693 if (Hero.y + 8 < y)
12694 dir = up;
12695 else
12696 dir = down;
12697 }
12698 else
12699 {
12700 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12701 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12702
12703 if((ddir <= -5.0*PI/8.0) && (ddir > -7.0*PI/8.0))
12704 {
12705 dir=l_down;
12706 }
12707 else if ((ddir <= -3.0*PI / 8.0) && (ddir > -5.0*PI / 8.0))
12708 {
12709 dir=down;
12710 }
12711 else if ((ddir <= -1.0*PI / 8.0) && (ddir > -3.0*PI / 8.0))
12712 {
12713 dir=r_down;
12714 }
12715 else if ((ddir <= 1.0*PI / 8.0) && (ddir > -1.0*PI / 8.0))
12716 {
12717 dir=right;
12718 }
12719 else if ((ddir <= 3.0*PI / 8.0) && (ddir > 1.0*PI / 8.0))
12720 {
12721 dir=r_up;
12722 }
12723 else if ((ddir <= 5.0*PI / 8.0) && (ddir > 3.0*PI / 8.0))
12724 {
12725 dir=up;
12726 }
12727 else if ((ddir <= 7.0*PI / 8.0) && (ddir > 5.0*PI / 8.0))
12728 {
12729 dir=l_up;
12730 }
12731 else
12732 {
12733 dir=left;
12734 }
12735 }
12736 }
12737
12738
12739 bool eSpinTile::animate(int32_t index)
12740 {
12741 if(switch_hooked) return enemy::animate(index);
12742 if(fallclk||drownclk) return enemy::animate(index);
12743 if(dying)
12744 {
12745 return Dead(index);
12746 }
12747
12748 if(clk==0)
12749 {
12750 removearmos(x,y,ffcactivated);
12751 }
12752
12753 ++misc;
12754
12755 if(misc==96)
12756 {
12757 facehero();
12758 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12759 double ddir=atan2_MSVC2022_FIX(double((Hero.y)-y),double(Hero.x-x));
12760 angular=true;
12761 angle=ddir;
12762 step=zslongToFix(dstep*100);
12763 }
12764
12765 if(y>186 || y<=-16 || x>272 || x<=-16)
12766 kickbucket();
12767
12768 sprite::move(step);
12769 return enemy::animate(index);
12770 }
12771
12772 void eSpinTile::draw(BITMAP *dest)
12773 {
12774 update_enemy_frame();
12775 y-=(misc>>4);
12776 yofs+=2;
12777 enemy::draw(dest);
12778 yofs-=2;
12779 y+=(misc>>4);
12780 }
12781
12782 void eSpinTile::drawshadow(BITMAP *dest, bool translucent)
12783 {
12784 flip = 0;
12785 shadowtile = wpnsbuf[spr_shadow].tile+(clk%4);
12786 yofs+=4;
12787 if(!shadow_overpit(this))
12788 enemy::drawshadow(dest, translucent);
12789 yofs-=4;
12790 }
12791
12792 20 eZora::eZora(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,0)
12793 20 {
12794 //these are here to bypass compiler warnings about unused arguments
12795 10 Clk=Clk;
12796 10 mainguy=false;
12797
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12798 /*if((x>-17 && x<0) && iswaterex(tmpscr->data[(((int32_t)y&0xF0)+((int32_t)x>>4))]))
12799 {
12800 clk=1;
12801 }*/
12802 //nets+880;
12803 10 SIZEflags = d->SIZEflags;
12804
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
12805 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
12806 // al_trace("Enemy txsz:%i\n", txsz);
12807
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
12808
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
12809
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
12810
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
12811
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
12812
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
12813 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
12814
1/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
12815
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
12816 {
12817 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
12818 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
12819 }
12820
12821
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
12822 10 }
12823
12824 3006 void eZora::facehero()
12825 {
12826
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2977 times.
3006 if(Hero.x-x==0)
12827 {
12828 29 dir=(Hero.y+8<y)?up:down;
12829 29 }
12830 else
12831 {
12832 double _MSVC2022_tmp1, _MSVC2022_tmp2;
12833 2977 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
12834
12835
3/4
✓ Branch 0 taken 108 times.
✓ Branch 1 taken 2869 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 108 times.
2977 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
12836 {
12837 108 dir=l_down;
12838 108 }
12839
3/4
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 2730 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 139 times.
2869 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
12840 {
12841 139 dir=down;
12842 139 }
12843
3/4
✓ Branch 0 taken 885 times.
✓ Branch 1 taken 1845 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 885 times.
2730 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
12844 {
12845 885 dir=r_down;
12846 885 }
12847
3/4
✓ Branch 0 taken 1130 times.
✓ Branch 1 taken 715 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1130 times.
1845 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
12848 {
12849 1130 dir=right;
12850 1130 }
12851
3/4
✓ Branch 0 taken 545 times.
✓ Branch 1 taken 170 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 545 times.
715 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
12852 {
12853 545 dir=r_up;
12854 545 }
12855
3/4
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 69 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 101 times.
170 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
12856 {
12857 101 dir=up;
12858 101 }
12859
2/4
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69 times.
✗ Branch 3 not taken.
69 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
12860 {
12861 69 dir=l_up;
12862 69 }
12863 else
12864 {
12865 dir=left;
12866 }
12867 }
12868 3006 }
12869
12870 4080 bool eZora::animate(int32_t index)
12871 {
12872
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4080 times.
4080 if(switch_hooked) return enemy::animate(index);
12873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4080 times.
4080 if(dying)
12874 return Dead(index);
12875
12876
2/2
✓ Branch 0 taken 4055 times.
✓ Branch 1 taken 25 times.
4080 if(clk==0)
12877 {
12878 25 removearmos(x,y,ffcactivated);
12879 25 }
12880
12881
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4080 times.
4080 if(watch)
12882 {
12883 ++clock_zoras[id];
12884 return true;
12885 }
12886
12887
2/2
✓ Branch 0 taken 1074 times.
✓ Branch 1 taken 3006 times.
4080 if(get_bit(quest_rules,qr_NEWENEMYTILES))
12888 {
12889 3006 facehero();
12890 3006 }
12891
12892
6/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 3973 times.
✓ Branch 4 taken 25 times.
✓ Branch 5 taken 15 times.
4080 switch(clk)
12893 {
12894 case 0: // reposition him
12895 {
12896 25 int32_t t=0;
12897 25 int32_t pos2=zc_oldrand()%160 + 16;
12898 25 bool placed=false;
12899
12900
4/4
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 25 times.
113 while(!placed && t<160)
12901 {
12902 38 int32_t watertype = iswaterex(tmpscr->data[pos2], currmap, currscr, -1, ((pos2)%16*16), ((pos2)&0xF0), false, true, true, (bool)(editorflags & ENEMY_FLAG7));
12903
4/6
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 25 times.
63 if(watertype && ((editorflags & ENEMY_FLAG6) ||
12904
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 ((combobuf[watertype].usrflags&cflag1) && (editorflags & ENEMY_FLAG5))
12905
3/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 25 times.
26 || (!(combobuf[watertype].usrflags&cflag1) && !(editorflags & ENEMY_FLAG5))) && (pos2&15)>0 && (pos2&15)<15)
12906 {
12907 25 x=(pos2&15)<<4;
12908 25 y=pos2&0xF0;
12909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (!(editorflags & ENEMY_FLAG8)) hp=guysbuf[id&0xFFF].hp; // refill life each time, unless the flag is checked.
12910 25 hxofs=1000; // avoid hit detection
12911 25 stunclk=0;
12912 25 placed=true;
12913 25 }
12914
12915 88 pos2+=19;
12916
12917
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 11 times.
88 if(pos2>=176)
12918 11 pos2-=160;
12919
12920 88 ++t;
12921 }
12922
12923
2/4
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25 times.
25 if(!placed || whistleclk>=88) // can't place him, he's gone
12924 return true;
12925
12926 }
12927 25 break;
12928
12929 case 35:
12930
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 7 times.
24 if(!get_bit(quest_rules,qr_NEWENEMYTILES))
12931 {
12932 7 dir=(Hero.y+8<y)?up:down;
12933 7 }
12934
12935 24 hxofs=0;
12936 24 break;
12937
12938 case 35+19:
12939 23 addEwpn(x,y,z,wpn,2,wdp,dir,getUID(), 0, fakez);
12940 23 sfx(wpnsfx(wpn),pan(int32_t(x)));
12941 23 break;
12942
12943 case 35+66:
12944 20 hxofs=1000;
12945 20 break;
12946
12947 case 198:
12948 15 clk=-1;
12949 15 break;
12950 }
12951
12952 4080 return enemy::animate(index);
12953 4080 }
12954
12955 4080 void eZora::draw(BITMAP *dest)
12956 {
12957
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 4005 times.
4080 if(clk<3)
12958 75 return;
12959
12960 4005 update_enemy_frame();
12961 4005 enemy::draw(dest);
12962 4080 }
12963
12964 bool eZora::isSubmerged() const
12965 {
12966 return ( clk < 3 );
12967 }
12968
12969
4/8
✓ Branch 0 taken 259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 259 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 259 times.
✗ Branch 7 not taken.
777 eStalfos::eStalfos(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
12970 518 {
12971 259 multishot= timer = fired = dashing = 0;
12972 259 hashero = false;
12973 259 dummy_bool[0]=false;
12974 259 shield= (flags&(inv_left | inv_right | inv_back |inv_front)) != 0;
12975
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
259 if(dmisc9==e9tARMOS && zc_oldrand()&1)
12976 {
12977 step=zslongToFix(dmisc10*100);
12978
12979 if(anim==aARMOS4) o_tile+=20;
12980 }
12981
12982
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
259 if(flags & guy_fadeflicker)
12983 {
12984 clk=0;
12985 superman = 1;
12986 fading=fade_flicker;
12987 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
12988 dir=down;
12989
12990 if(!canmove(down,(zfix)8,spw_none,false))
12991 clk3=int32_t(13.0/step);
12992 }
12993
1/2
✓ Branch 0 taken 259 times.
✗ Branch 1 not taken.
259 else if(flags & guy_fadeinstant)
12994 {
12995 clk=0;
12996 }
12997
12998
1/2
✓ Branch 0 taken 259 times.
✗ Branch 1 not taken.
259 shadowdistance = 0;
12999 259 clk4 = clk5 = 0;
13000 //nets+2380;
13001 259 SIZEflags = d->SIZEflags;
13002
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
259 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
13003 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
13004 // al_trace("Enemy txsz:%i\n", txsz);
13005
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
259 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
13006
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
259 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
13007
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
259 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
13008
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
259 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
13009
1/2
✓ Branch 0 taken 259 times.
✗ Branch 1 not taken.
259 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
13010
1/2
✓ Branch 0 taken 259 times.
✗ Branch 1 not taken.
259 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
13011 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
13012
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
259 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
13013
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
259 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
13014 {
13015 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
13016 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
13017 }
13018
13019
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
259 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
13020 259 }
13021
13022 136522 bool eStalfos::animate(int32_t index)
13023 {
13024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 136522 times.
136522 if(switch_hooked) return enemy::animate(index);
13025
2/4
✓ Branch 0 taken 136522 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 136522 times.
136522 if(fallclk||drownclk)
13026 {
13027 return enemy::animate(index);
13028 }
13029
2/2
✓ Branch 0 taken 2862 times.
✓ Branch 1 taken 133660 times.
136522 if(dying)
13030 {
13031
1/2
✓ Branch 0 taken 2862 times.
✗ Branch 1 not taken.
2862 if(hashero)
13032 {
13033 Hero.setEaten(0);
13034 hashero=false;
13035 }
13036
13037
1/14
✗ Branch 0 not taken.
✓ Branch 1 taken 2862 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2862 if(dmisc9==e9tROPE && dmisc2==e2tBOMBCHU && !fired && (hp<=0 && !immortal) && hp>-1000 && wpn>wEnemyWeapons)
13038 {
13039 hp=-1000;
13040 weapon *ew=new weapon(x,y,z, wpn, 0, dmisc4, dir,-1,getUID(),false);
13041 Ewpns.add(ew);
13042 ew->fakez = fakez;
13043
13044 if(wpn==ewSBomb || wpn==ewBomb)
13045 {
13046 ew->step=0;
13047 ew->id=wpn;
13048 ew->misc=50;
13049 ew->clk=48;
13050 }
13051
13052 fired=true;
13053 }
13054
5/6
✓ Branch 0 taken 1854 times.
✓ Branch 1 taken 1008 times.
✓ Branch 2 taken 1710 times.
✓ Branch 3 taken 144 times.
✓ Branch 4 taken 1710 times.
✗ Branch 5 not taken.
2862 else if(wpn && wpn!=ewBrang && dmisc2==e2tFIREOCTO) // Fire Octo
13055 {
13056 if(!dummy_bool[0])
13057 {
13058 int32_t wpn2 = wpn+dmisc3;
13059
13060 if(wpn2 <= wEnemyWeapons || wpn2 >= wMax)
13061 {
13062 wpn2=wpn;
13063 }
13064
13065 dummy_bool[0]=true;
13066 addEwpn(x,y,z,wpn2,0,dmisc4,up, getUID(), 0, fakez);
13067 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13068 addEwpn(x,y,z,wpn2,0,dmisc4,down, getUID(), 0, fakez);
13069 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13070 addEwpn(x,y,z,wpn2,0,dmisc4,left, getUID(), 0, fakez);
13071 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13072 addEwpn(x,y,z,wpn2,0,dmisc4,right, getUID(), 0, fakez);
13073 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13074 addEwpn(x,y,z,wpn2,0,dmisc4,l_up, getUID(), 0, fakez);
13075 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13076 addEwpn(x,y,z,wpn2,0,dmisc4,r_up, getUID(), 0, fakez);
13077 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13078 addEwpn(x,y,z,wpn2,0,dmisc4,l_down, getUID(), 0, fakez);
13079 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13080 addEwpn(x,y,z,wpn2,0,dmisc4,r_down, getUID(), 0, fakez);
13081 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
13082 sfx(wpnsfx(wpn2),pan(int32_t(x)));
13083 }
13084 }
13085
13086 2862 KillWeapon();
13087 2862 return Dead(index);
13088 }
13089 //vire split
13090 //2.10 checked !fslide(), but nothing uses that now anyway. -Z
13091 //Perhaps the problem occurs when vires die because they have < 0 HP, in this check?
13092
8/14
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 133501 times.
✓ Branch 2 taken 159 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 159 times.
✓ Branch 6 taken 618 times.
✓ Branch 7 taken 133042 times.
✓ Branch 8 taken 618 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 618 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
133660 else if(((hp<=0 && !immortal) && dmisc2==e2tSPLIT) || (dmisc2==e2tSPLITHIT && hp>0 && hp<guysbuf[id&0xFFF].hp && !slide() && (sclk&255)<=1)) //Split into enemies
13093 {
13094 stop_bgsfx(index);
13095 int32_t kids = guys.Count();
13096 int32_t id2=dmisc3;
13097 for(int32_t i=0; i < dmisc4; i++)
13098 {
13099 // if (addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : ((i+1)<<12)),-21-(i%4)))
13100 if(addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : ((editorflags & ENEMY_FLAG5) ? 0 : (i<<12))),-21-(i%4)))
13101 ((enemy*)guys.spr(kids+i))->count_enemy = false;
13102 }
13103
13104 if(itemguy) // Hand down the carried item
13105 {
13106 guycarryingitem = guys.Count()-1;
13107 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
13108 itemguy = false;
13109 }
13110
13111 if(hashero)
13112 {
13113 Hero.setEaten(0);
13114 hashero=false;
13115 }
13116
13117 if(deadsfx > 0 && dmisc2==e2tSPLIT)
13118 sfx(deadsfx,pan(int32_t(x)));
13119
13120 return true;
13121 }
13122 /*
13123 else if((dmisc2==e2tSPLITHIT && (hp<=0 && !immortal) &&!slide())) //Possible vires fix; or could cause goodness knows what. -Z
13124 {
13125 stop_bgsfx(index);
13126 int32_t kids = guys.Count();
13127 int32_t id2=dmisc3;
13128
13129 for(int32_t i=0; i < dmisc4; i++)
13130 {
13131 // if (addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : ((i+1)<<12)),-21-(i%4)))
13132 if(addenemy(x,y,id2+(guysbuf[id2].family==eeKEESE ? 0 : (i<<12)),-21-(i%4)))
13133 ((enemy*)guys.spr(kids+i))->count_enemy = false;
13134 }
13135
13136 if(itemguy) // Hand down the carried item
13137 {
13138 guycarryingitem = guys.Count()-1;
13139 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
13140 itemguy = false;
13141 }
13142
13143 if(hashero)
13144 {
13145 Hero.setEaten(0);
13146 hashero=false;
13147 }
13148
13149 return true;
13150 }
13151 */
13152
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 133650 times.
133660 if(fading)
13153 {
13154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(++clk4 > 60)
13155 {
13156 clk4=0;
13157 superman=0;
13158 fading=0;
13159
13160 if(flags2&cmbflag_armos && z==0 && fakez == 0)
13161 {
13162 //if a custom size (not 16px by 16px)
13163
13164 //if a custom size (not 16px by 16px)
13165 if (ffcactivated)
13166 removearmosffc(ffcactivated-1);
13167 else
13168 {
13169 if (txsz > 1 || tysz > 1 || (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) || (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) )//remove more than one combo based on enemy size
13170 {
13171 //zprint("spawn big enemy from armos\n");
13172 //if removing a block, then adjust y by -1 as the enemy spawns at y+1
13173 for(int32_t dx = 0; dx < tysz; dx ++)
13174 {
13175 for(int32_t dy = 0; dy < tysz; dy++)
13176 {
13177 removearmos((int32_t)x+(dx*16),(int32_t)y+(dy*16)+1);
13178 did_armos = false;
13179 }
13180 removearmos((int32_t)x+(dx*16), (int32_t)y+((tysz-1)*16)+1);
13181 did_armos = false;
13182 }
13183 for(int32_t dy = 0; dy < tysz; dy ++)
13184 {
13185 removearmos((int32_t)x+((txsz-1)*16), (int32_t)y+(dy*16)+1);
13186 did_armos = false;
13187 }
13188 removearmos((int32_t)x+((txsz-1)*16), (int32_t)y+((tysz-1)*16)+1);
13189 }
13190 else removearmos(x,y);
13191 }
13192 /*
13193 if (txsz > 1 || tysz > 1 || (SIZEflags&guyflagOVERRIDE_HIT_WIDTH) || (SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) )//remove more than one combo based on enemy size
13194 {
13195 //if removing a block, then adjust y by -1 as the enemy spawns at y+1
13196 for(int32_t dx = 0; dx < hxsz; dx += 16)
13197 {
13198 for(int32_t dy = 0; dy < hysz; dy += 16)
13199 {
13200 removearmos((int32_t)x+dx+hxofs,(int32_t)y+dy+hyofs+1,ffcactivated);
13201 did_armos = false;
13202 }
13203 removearmos((int32_t)x+dx+hxofs, (int32_t)y+hyofs+(hysz-1)-1,ffcactivated);
13204 did_armos = false;
13205 }
13206 for(int32_t dy = 0; dy < hysz; dy += 16)
13207 {
13208 removearmos((int32_t)x+hxofs+(hxsz-1), (int32_t)y+dy+hyofs-1,ffcactivated);
13209 did_armos = false;
13210 }
13211 removearmos((int32_t)x+hxofs+(hxsz-1), (int32_t)y+hyofs+(hysz-1)-1,ffcactivated);
13212 }
13213 else removearmos(x,y,ffcactivated);
13214 */
13215
13216 }
13217
13218 clk2=0;
13219
13220 newdir();
13221 }
13222 10 else return enemy::animate(index);
13223 }
13224
1/8
✗ Branch 0 not taken.
✓ Branch 1 taken 133650 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
133650 else if(flags2&cmbflag_armos && z==0 && fakez == 0 && clk==0)
13225 removearmos(x,y,ffcactivated);
13226
13227
13228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133650 times.
133650 if(hashero)
13229 {
13230 Hero.setX(x);
13231 Hero.setY(y);
13232 ++clk2;
13233
13234 if(clk2==(dmisc8==0 ? 95 : dmisc8))
13235 {
13236 switch(dmisc7)
13237 {
13238 case e7tEATITEMS:
13239 {
13240 for(int32_t i=0; i<MAXITEMS; i++)
13241 {
13242 if(itemsbuf[i].flags&ITEM_EDIBLE)
13243 game->set_item(i, false);
13244 }
13245
13246 break;
13247 }
13248
13249 case e7tEATMAGIC:
13250 game->change_dmagic(-1*game->get_magicdrainrate());
13251 break;
13252
13253 case e7tEATRUPEES:
13254 game->change_drupy(-1);
13255 break;
13256 }
13257
13258 clk2=0;
13259 }
13260
13261 if((clk&0x18)==8) // stop its animation on the middle frame
13262 --clk;
13263 }
13264
4/4
✓ Branch 0 taken 9746 times.
✓ Branch 1 taken 123904 times.
✓ Branch 2 taken 6464 times.
✓ Branch 3 taken 3282 times.
133650 else if(!(wpn==ewBrang && WeaponOut())) //WeaponOut uses misc
13265 {
13266 // Movement engine
13267
3/6
✓ Branch 0 taken 5859 times.
✓ Branch 1 taken 124509 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 124509 times.
✗ Branch 5 not taken.
130368 if(clk>=0) switch(id>>12)
13268 {
13269 case 0: // Normal movement
13270
13271 /*
13272 if((dmisc9==e9tLEEVER || dmisc9==e9tZ3LEEVER) && !slide()) //Leever
13273 {
13274 // Overloading clk4 (Tribble clock) here...
13275 step=17/100.0;
13276 if(clk4<32) misc=1;
13277 else if(clk4<48) misc=2;
13278 else if(clk4<300) { misc=3; step = dstep/100.0; }
13279 else if(clk4<316) misc=2;
13280 else if(clk4<412) misc=1;
13281 else if(clk4<540) { misc=0; step=0; }
13282 else clk4=0;
13283 if(clk4==48) clk=0;
13284 hxofs=(misc>=2)?0:1000;
13285 if (dmisc9==e9tLEEVER)
13286 variable_walk(rate, homing, 0);
13287 else
13288 variable_walk_8(rate, homing, 4, 0);
13289 break;
13290 }
13291 */
13292
2/4
✓ Branch 0 taken 124509 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 124509 times.
124509 if(dmisc9==e9tVIRE || dmisc9==e9tPOLSVOICE) //Vire
13293 {
13294 vire_hop();
13295 break;
13296 }
13297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 124509 times.
124509 else if(dmisc9==e9tROPE) //Rope charge
13298 {
13299 if(!fired && dashing && !stunclk && !watch && !frozenclock)
13300 {
13301 if(dmisc2==e2tBOMBCHU && HeroInRange(16) && wpn+dmisc3 > wEnemyWeapons) //Bombchu
13302 {
13303
13304 if ( get_bit(quest_rules,qr_BOMBCHUSUPERBOMB) )
13305 {
13306 hp=-1000;
13307
13308 if(wpn+dmisc3 > wEnemyWeapons && wpn+dmisc3 < wMax)
13309 {
13310 weapon *ew=new weapon(x,y,z, wpn+dmisc3, 0, dmisc4, dir,-1,getUID());
13311 Ewpns.add(ew);
13312 ew->fakez = fakez;
13313
13314 if(wpn==ewSBomb || wpn==ewBomb)
13315 {
13316 ew->step=0;
13317 ew->id=wpn+dmisc3;
13318 ew->misc=50;
13319 ew->clk=48;
13320 }
13321
13322 fired=true;
13323 }
13324 else
13325 {
13326 weapon *ew=new weapon(x,y,z, wpn, 0, dmisc4, dir,-1,getUID());
13327 Ewpns.add(ew);
13328 ew->fakez = fakez;
13329
13330 if(wpn==ewSBomb || wpn==ewBomb)
13331 {
13332 ew->step=0;
13333 ew->id=wpn;
13334 ew->misc=50;
13335 ew->clk=48;
13336 }
13337
13338 fired=true;
13339 }
13340 }
13341
13342 else
13343 {
13344 hp=-1000;
13345
13346 int32_t wpn2;
13347 if(wpn+dmisc3 > wEnemyWeapons && wpn+dmisc3 < wMax)
13348 wpn2=wpn;
13349 else
13350 wpn2=wpn;
13351
13352 weapon *ew=new weapon(x,y,z, wpn2, 0, dmisc4, dir,-1,getUID());
13353 Ewpns.add(ew);
13354 ew->fakez = fakez;
13355
13356 if(wpn2==ewSBomb || wpn2==ewBomb)
13357 {
13358 ew->step=0;
13359 ew->id=wpn2;
13360 ew->misc=50;
13361 ew->clk=48;
13362 }
13363
13364 fired=true;
13365 }
13366 }
13367 }
13368
13369 charge_attack();
13370 break;
13371 }
13372 /*
13373 * Boomerang-throwers have a halt count of 1
13374 * Zols have a halt count of (zc_oldrand()&7)<<4
13375 * Gels have a halt count of ((zc_oldrand()&7)<<3)+2
13376 * Everything else has 48
13377 */
13378 else
13379 {
13380
2/2
✓ Branch 0 taken 6280 times.
✓ Branch 1 taken 118229 times.
124509 if(wpn==ewBrang) // Goriya
13381 {
13382 6280 halting_walk(rate,homing,0,hrate, 1);
13383 6280 }
13384
3/4
✓ Branch 0 taken 118229 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32949 times.
✓ Branch 3 taken 85280 times.
118229 else if(dmisc9==e9tNORMAL && wpn==0)
13385 {
13386
2/2
✓ Branch 0 taken 570 times.
✓ Branch 1 taken 84710 times.
85280 if(dmisc2==e2tSPLITHIT) // Zol
13387 {
13388 570 halting_walk(rate,homing,0,hrate,(zc_oldrand()&7)<<4);
13389 570 }
13390
4/4
✓ Branch 0 taken 9569 times.
✓ Branch 1 taken 75141 times.
✓ Branch 2 taken 4219 times.
✓ Branch 3 taken 5350 times.
84710 else if(frate<=8 && starting_hp==1) // Gel
13391 {
13392 5350 halting_walk(rate,homing,0,hrate,((zc_oldrand()&7)<<3)+2);
13393 5350 }
13394 else // Other
13395 {
13396 79360 halting_walk(rate,homing,0,hrate, 48);
13397 }
13398 85280 }
13399 else // Other
13400 {
13401 32949 halting_walk(rate,homing,0,hrate, 48);
13402 }
13403 }
13404
13405 //if not in midair, and Hero's swinging sword is nearby, jump.
13406 /*if (dmisc9==e9tZ3STALFOS && z==0 && (!(isSideViewGravity()) || !_walkflag(x,y+16,0))
13407 && Hero.getAttackClk()==5 && Hero.getAttack()==wSword && distance(x,y,Hero.getX(),Hero.getY())<32)
13408 {
13409 facehero(false);
13410 sclk=16+((dir^1)<<8);
13411 fall=-FEATHERJUMP;
13412 sfx(WAV_ZN1JUMP,pan(int32_t(x)));
13413 }*/
13414 124509 break;
13415
13416 // Following cases are for just after creation-by-splitting.
13417 case 1:
13418 if(misc==1)
13419 {
13420 dir=up;
13421 step=8;
13422 }
13423
13424 if(misc<=2)
13425 {
13426 move(step);
13427
13428 if(!canmove(dir,(zfix)0,0,false))
13429 dir=down;
13430 }
13431
13432 if(misc==3)
13433 {
13434 if(canmove(right,(zfix)16,0,false))
13435 x+=16;
13436 }
13437
13438 ++misc;
13439 break;
13440
13441 case 2:
13442 if(misc==1)
13443 {
13444 dir=down;
13445 step=8;
13446 }
13447
13448 if(misc<=2)
13449 {
13450 move(step);
13451 /*
13452 if(!canmove(dir,(zfix)0,0,false))
13453 dir=up;
13454 */
13455 }
13456
13457 if(misc==3)
13458 {
13459 if(canmove(left,(zfix)16,0,false))
13460 x-=16;
13461 }
13462
13463 ++misc;
13464 break;
13465
13466 default:
13467 if(misc==1)
13468 {
13469 dir=(zc_oldrand()%4);
13470 step=8;
13471 }
13472
13473 if(misc<=2)
13474 {
13475 move(step);
13476
13477 if(!canmove(dir,(zfix)0,0,false))
13478 dir=dir^1;
13479 }
13480
13481 if(misc==3)
13482 {
13483 if(dir >= left && canmove(dir,(zfix)16,0,false))
13484 x+=(dir==left ? -16 : 16);
13485 }
13486
13487 ++misc;
13488 break;
13489 124509 }
13490
13491
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 130368 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
130368 if(id>>12 && misc>=4) //recently spawned by a split enemy
13492 {
13493 id&=0xFFF;
13494 step = zslongToFix(dstep*100);
13495
13496 if(x<32) x=32;
13497
13498 if(x>208) x=208;
13499
13500 if(y<32) y=32;
13501
13502 if(y>128) y=128;
13503
13504 misc=3;
13505 }
13506 130368 }
13507 else
13508 {
13509 //sfx(wpnsfx(wpn),pan(int32_t(x)));
13510
1/2
✓ Branch 0 taken 3282 times.
✗ Branch 1 not taken.
3282 if(clk2>2) clk2--;
13511 }
13512
13513 // Fire Zol
13514
3/8
✓ Branch 0 taken 45988 times.
✓ Branch 1 taken 87662 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45988 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
133650 if(wpn && dmisc1==e1tEACHTILE && clk2==1 && !hclk)
13515 {
13516 addEwpn(x,y,z,wpn,0,wdp,dir, getUID(), 0, fakez);
13517 sfx(wpnsfx(wpn),pan(int32_t(x)));
13518
13519 int32_t i=Ewpns.Count()-1;
13520 weapon *ew = (weapon*)(Ewpns.spr(i));
13521
13522 if(wpn==ewFIRETRAIL && wpnsbuf[ewFIRETRAIL].frames>1)
13523 {
13524 ew->aframe=zc_oldrand()%wpnsbuf[ewFIRETRAIL].frames;
13525 if ( ew->do_animation ) ew->tile+=ew->aframe;
13526 }
13527 }
13528 // Goriya
13529
12/16
✓ Branch 0 taken 9746 times.
✓ Branch 1 taken 123904 times.
✓ Branch 2 taken 3344 times.
✓ Branch 3 taken 6402 times.
✓ Branch 4 taken 3225 times.
✓ Branch 5 taken 119 times.
✓ Branch 6 taken 3225 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3225 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3225 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3225 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3178 times.
✓ Branch 15 taken 47 times.
133650 else if(wpn==ewBrang && clk2==1 && sclk==0 && !stunclk && !frozenclock && !watch && wpn && !WeaponOut())
13530 {
13531 47 misc=index+100;
13532
7/14
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 47 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 47 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 47 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 47 times.
✗ Branch 13 not taken.
47 Ewpns.add(new weapon(x,y-fakez,z,wpn,misc,wdp,dir, -1,getUID(),false));
13533 47 ((weapon*)Ewpns.spr(Ewpns.Count()-1))->dummy_bool[0]=false;
13534
13535
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 if(dmisc1==2)
13536 {
13537 int32_t ndir=dir;
13538
13539 if(Hero.x-x==0)
13540 {
13541 ndir=(Hero.y+8<y)?up:down;
13542 }
13543 else //turn to face Hero
13544 {
13545 double _MSVC2022_tmp1, _MSVC2022_tmp2;
13546 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
13547
13548 if((ddir<=(((-2)*PI)/8))&&(ddir>(((-6)*PI)/8)))
13549 {
13550 ndir=down;
13551 }
13552 else if((ddir<=(((2)*PI)/8))&&(ddir>(((-2)*PI)/8)))
13553 {
13554 ndir=right;
13555 }
13556 else if((ddir<=(((6)*PI)/8))&&(ddir>(((2)*PI)/8)))
13557 {
13558 ndir=up;
13559 }
13560 else
13561 {
13562 ndir=left;
13563 }
13564 }
13565
13566 ((weapon*)Ewpns.spr(Ewpns.Count()-1))->dummy_bool[0]=true;
13567
13568 if(canmove(ndir,false))
13569 {
13570 dir=ndir;
13571 }
13572 }
13573 47 }
13574
13/16
✓ Branch 0 taken 132813 times.
✓ Branch 1 taken 790 times.
✓ Branch 2 taken 790 times.
✓ Branch 3 taken 132813 times.
✓ Branch 4 taken 228 times.
✓ Branch 5 taken 562 times.
✓ Branch 6 taken 228 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 227 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 186 times.
✓ Branch 11 taken 41 times.
✓ Branch 12 taken 186 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 186 times.
133603 else if((clk2==16 || dmisc1==e1tCONSTANT) && dmisc1!=e1tEACHTILE && wpn && wpn!=ewBrang && sclk==0 && !stunclk && !frozenclock && !watch)
13575
1/3
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
186 switch(dmisc1)
13576 {
13577 case e1tCONSTANT: //Deathnut
13578 {
13579 // Overloading clk5 (Like Like clock) to avoid making another clock just for this attack...
13580 if(clk5>64)
13581 {
13582 clk5=0;
13583 fired=false;
13584 }
13585
13586 clk5+=(zc_oldrand()&3);
13587
13588 if((clk5>24)&&(clk5<52))
13589 {
13590 if ( do_animation )tile+=20; //firing
13591
13592 if(!fired&&(clk5>=38))
13593 {
13594 Ewpns.add(new weapon(x,y,z, wpn, 0, wdp, dir, -1,getUID(),false));
13595 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
13596 sfx(wpnsfx(wpn),pan(int32_t(x)));
13597 fired=true;
13598 }
13599 }
13600
13601 break;
13602 }
13603
13604 case e1tFIREOCTO: //Fire Octo
13605 timer=zc_oldrand()%50+50;
13606 break;
13607
13608 default:
13609 186 FireWeapon();
13610 186 break;
13611 186 }
13612
13613 /* Fire again if:
13614 * - clk2 about to run out
13615 * - not already double-firing (dmisc1 is 1)
13616 * - not carrying Hero
13617 * - one in 0xF chance
13618 */
13619
8/10
✓ Branch 0 taken 4104 times.
✓ Branch 1 taken 129546 times.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 4052 times.
✓ Branch 4 taken 52 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 52 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 50 times.
133650 if(clk2==1 && (multishot < dmisc6) && dmisc1 != e1tEACHTILE && !hashero && !(zc_oldrand()&15))
13620 {
13621 #if 1
13622 2 newdir(rate, homing, grumble);
13623 #else
13624 dir^=2;
13625 #endif
13626 2 clk2=28;
13627 2 ++multishot;
13628 2 }
13629
13630
2/2
✓ Branch 0 taken 39919 times.
✓ Branch 1 taken 93731 times.
133650 if(clk2==0)
13631 {
13632 93731 multishot = 0;
13633 93731 }
13634
13635
1/2
✓ Branch 0 taken 133650 times.
✗ Branch 1 not taken.
133650 if(timer) //Fire Octo
13636 {
13637 clk2=15; //this keeps the octo in place until he's done firing
13638
13639 if(!(timer%4))
13640 {
13641 FireBreath(false);
13642 }
13643
13644 --timer;
13645 }
13646
13647
1/2
✓ Branch 0 taken 133650 times.
✗ Branch 1 not taken.
133650 if(dmisc2==e2tTRIBBLE)
13648 ++clk4;
13649
13650
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 133650 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 133650 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
133650 if(clk4==(dmisc5 ? dmisc5 : 256) && (dmisc2==e2tTRIBBLE) && dmisc3 && dmisc4)
13651 {
13652 int32_t kids = guys.Count();
13653 int32_t id2=dmisc3;
13654
13655 for(int32_t i=0; i<dmisc4; i++)
13656 {
13657 if(addenemy(x,y,id2,-24))
13658 {
13659 if(itemguy) // Hand down the carried item
13660 {
13661 guycarryingitem = guys.Count()-1;
13662 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
13663 itemguy = false;
13664 }
13665
13666 ((enemy*)guys.spr(kids+i))->count_enemy = false;
13667 }
13668 }
13669
13670 if(hashero)
13671 {
13672 Hero.setEaten(0);
13673 hashero=false;
13674 }
13675
13676 stop_bgsfx(index);
13677 return true;
13678 }
13679
13680 133650 return enemy::animate(index);
13681 136522 }
13682
13683 136536 void eStalfos::draw(BITMAP *dest)
13684 {
13685 /*if ((dmisc9==e9tLEEVER || dmisc9==e9tZ3LEEVER) && misc<=0) //Submerged
13686 {
13687 clk4--; //Kludge
13688 return;
13689 }*/
13690
13691 /*if ((dmisc9==e9tLEEVER || dmisc9==e9tZ3LEEVER) && misc>1)
13692 {
13693 cs = dcset;
13694 }*/
13695 136536 update_enemy_frame();
13696
13697
3/8
✓ Branch 0 taken 136536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 136536 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 136536 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
136536 if(!fallclk&&!drownclk&&(dmisc2==e2tBOMBCHU)&&dashing)
13698 {
13699 if ( do_animation )tile+=20;
13700 }
13701
13702 136536 enemy::draw(dest);
13703 136536 }
13704
13705 82108 void eStalfos::drawshadow(BITMAP *dest, bool translucent)
13706 {
13707 82108 int32_t tempy=yofs;
13708
13709 /*
13710 if (clk6 && dir>=left && !get_bit(quest_rules,qr_ENEMIESZAXIS)) {
13711 flip = 0;
13712 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
13713 (clk/(frate/4)):((clk>=(frate>>1))?1:0);
13714 shadowtile = wpnsbuf[spr_shadow].tile+f2;
13715 yofs+=(((int32_t)y+17)&0xF0)-y;
13716 yofs+=8;
13717 }
13718 */
13719
2/4
✓ Branch 0 taken 82108 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 82108 times.
✗ Branch 3 not taken.
82108 if((dmisc9 == e9tPOLSVOICE || dmisc9==e9tVIRE) && !get_bit(quest_rules,qr_ENEMIESZAXIS))
13720 {
13721 flip = 0;
13722 int32_t fdiv = frate/4;
13723 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
13724
13725 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
13726 efrate:((clk>=(frate>>1))?1:0);
13727 shadowtile = wpnsbuf[spr_shadow].tile;
13728
13729 if(get_bit(quest_rules,qr_NEWENEMYTILES))
13730 {
13731 shadowtile+=f2;
13732 }
13733 else
13734 {
13735 shadowtile+=f2?1:0;
13736 }
13737
13738 yofs+=shadowdistance;
13739 yofs+=8;
13740 }
13741
2/4
✓ Branch 0 taken 82108 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 82108 times.
✗ Branch 3 not taken.
82108 if((dmisc9 == e9tPOLSVOICE || dmisc9==e9tVIRE) && !get_bit(quest_rules,qr_POLVIRE_NO_SHADOW))
13742 {
13743 flip = 0;
13744 int32_t fdiv = frate/4;
13745 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
13746
13747 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
13748 efrate:((clk>=(frate>>1))?1:0);
13749 shadowtile = wpnsbuf[spr_shadow].tile;
13750
13751 if(get_bit(quest_rules,qr_NEWENEMYTILES))
13752 {
13753 shadowtile+=f2;
13754 }
13755 else
13756 {
13757 shadowtile+=f2?1:0;
13758 }
13759 }
13760
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82108 times.
82108 if(!shadow_overpit(this))
13761 82108 enemy::drawshadow(dest, translucent);
13762 82108 yofs=tempy;
13763 82108 }
13764
13765 431 int32_t eStalfos::takehit(weapon *w)
13766 {
13767 431 int32_t wpnId = w->id;
13768 431 int32_t wpnDir = w->dir;
13769
13770
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 431 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
431 if(wpnId==wHammer && shield && (flags & guy_bkshield)
13771 && ((flags&inv_front && wpnDir==(dir^down)) || (flags&inv_back && wpnDir==(dir^up))
13772 || (flags&inv_left && wpnDir==(dir^left)) || (flags&inv_right && wpnDir==(dir^right))))
13773 {
13774 shield = false;
13775 flags &= ~(inv_left|inv_right|inv_back|inv_front);
13776
13777 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
13778 o_tile=s_tile;
13779 }
13780
13781 431 int32_t ret = enemy::takehit(w);
13782
13783
3/4
✓ Branch 0 taken 161 times.
✓ Branch 1 taken 270 times.
✓ Branch 2 taken 161 times.
✗ Branch 3 not taken.
431 if(sclk && dmisc2==e2tSPLITHIT)
13784 sclk+=128; //Fuck these arbitrary values with no explanation. Fuck vires, too. -Z
13785
13786 431 return ret;
13787 }
13788
13789 void eStalfos::charge_attack()
13790 {
13791 if(slide())
13792 return;
13793
13794 if(clk<0 || dir<0 || stunclk || watch || ceiling || frozenclock )
13795 return;
13796
13797 if(clk3<=0)
13798 {
13799 fix_coords(true);
13800
13801 if(!dashing)
13802 {
13803 int32_t ldir = lined_up(7,false);
13804
13805 if(ldir!=-1 && canmove(ldir,false))
13806 {
13807 dir=ldir;
13808 dashing=true;
13809 step=zslongToFix(dstep*100)+1;
13810 }
13811 else newdir(4,0,0);
13812 }
13813
13814 if(!canmove(dir,false))
13815 {
13816 step=zslongToFix(dstep*100);
13817 newdir();
13818 dashing=false;
13819 }
13820
13821 zfix div = step;
13822
13823 if(div == 0)
13824 div = 1;
13825
13826 clk3=(int32_t)(16.0/div);
13827 return;
13828 }
13829
13830 move(step);
13831 --clk3;
13832 }
13833
13834 void eStalfos::vire_hop()
13835 {
13836 //if ( sclk > 0 ) return; //Don't hop during knockback.
13837
13838 // if(dmisc9!=e9tPOLSVOICE)
13839 // {
13840 // //if( slide() /*sclk!=0*/ && dmisc2==e2tSPLIT) //Vires with split on hit, only! -Z
13841 // if( sclk!=0 && dmisc2==e2tSPLIT) //Vires with split on hit, only! -Z
13842 // return; //the enemy should split if it is sliding!
13843 // //else sclk=0; //might need this here, too. -Z
13844 // }
13845 if(dmisc9!=e9tPOLSVOICE)
13846 {
13847 if(sclk!=0)
13848 {
13849 if (dmisc2==e2tSPLITHIT) return;
13850 //return;
13851 }
13852 }
13853 else sclk=0;
13854
13855 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
13856 return;
13857
13858 int32_t jump_width = (dmisc9==e9tPOLSVOICE) ? 2 : 1;
13859 int32_t jump_height = (dmisc9==e9tPOLSVOICE) ? 27 : 16;
13860
13861 y=floor_y;
13862
13863 if(clk3<=0)
13864 {
13865 fix_coords();
13866
13867 //z=0;
13868 //if we're not in the middle of a jump or if we can't complete the current jump in the current direction
13869 //if(clk2<=0 || !canmove(dir,(zfix)1,spw_floater,false) || (isSideViewGravity() && isOnSideviewPlatform()))
13870 if(clk2<=0 || !canmove(dir,(zfix)1,spw_floater,false) || (isSideViewGravity() && (isOnSideviewPlatform() || !(moveflags & FLAG_OBEYS_GRAV)))) //Vires in old quests
13871 newdir(rate,homing,dmisc9==e9tPOLSVOICE ? spw_floater : spw_none);
13872
13873 if(clk2<=0)
13874 {
13875 //z=0;
13876 if(!canmove(dir,(zfix)2,spw_none,false) || m_walkflag(x,y,spw_none, dir) || (zc_oldrand()&15)>=hrate)
13877 {
13878
13879 clk2=(wpn==ewBrang ? 1 : int32_t((16.0*jump_width)/step.getFloat()));
13880 /*if (dmisc9==e9tPOLSVOICE )
13881 {
13882 zprint2("polsvoice jump_width is: %d\n", jump_width);
13883 zprint2("polsvoice raw step is: %d\n", step);
13884 zprint2("polsvoice step.getInt() is: %d\n", step.getInt());
13885 zprint2("setting clk2 on polsvoice to: %d\n", clk2);
13886 }
13887 else
13888 {
13889 zprint2("vire jump_width is: %d\n", jump_width);
13890 zprint2("vire raw step is: %d\n", step);
13891 zprint2("vire step.getInt() is: %d\n", step.getInt());
13892 zprint2("setting clk2 on vire to: %d\n", clk2);
13893 }
13894 */
13895 }
13896 }
13897
13898 if(dmisc9!=e9tPOLSVOICE && dir>=left) //if we're moving left or right
13899 {
13900 clk2=int32_t((16.0*jump_width)/step.getFloat());
13901 }
13902
13903 clk3=int32_t(16.0/step.getFloat());
13904 }
13905
13906 --clk3;
13907
13908 if(dmisc9==e9tPOLSVOICE || clk2>0)
13909 move(step);
13910
13911 floor_y=y;
13912 clk2--;
13913
13914 //if we're in the middle of a jump
13915 if(clk2>0 && (dir>=left || dmisc9==e9tPOLSVOICE))
13916 {
13917 int32_t h = fixtoi(fixsin(itofix(clk2*128*step/(16*jump_width)))*jump_height);
13918
13919 if(get_bit(quest_rules,qr_ENEMIESZAXIS) && !(isSideViewGravity()))
13920 {
13921 if (moveflags & FLAG_USE_FAKE_Z) fakez=h;
13922 else z=h;
13923 }
13924 else
13925 {
13926 //y+=fixtoi(fixsin(itofix((clk2+1)*128*step/(16*jump_width)))*jump_height);
13927 //y-=h;
13928 y=floor_y-h;
13929 shadowdistance=h;
13930 }
13931 }
13932 else
13933 shadowdistance = 0;
13934 }
13935
13936 void eStalfos::eathero()
13937 {
13938 if(!hashero && Hero.getEaten()==0 && Hero.getAction() != hopping && Hero.getAction() != swimming)
13939 {
13940 hashero=true;
13941 y=floor_y;
13942 z=0;
13943
13944 if(Hero.isSwimming())
13945 {
13946 Hero.setX(x);
13947 Hero.setY(y);
13948 }
13949 else
13950 {
13951 x=Hero.getX();
13952 y=Hero.getY();
13953 }
13954
13955 clk2=0;
13956 }
13957 }
13958
13959 12971 bool eStalfos::WeaponOut()
13960 {
13961
2/2
✓ Branch 0 taken 14176 times.
✓ Branch 1 taken 6511 times.
20687 for(int32_t i=0; i<Ewpns.Count(); i++)
13962 {
13963
3/4
✓ Branch 0 taken 6460 times.
✓ Branch 1 taken 7716 times.
✓ Branch 2 taken 6460 times.
✗ Branch 3 not taken.
14176 if(((weapon*)Ewpns.spr(i))->parentid==getUID() && Ewpns.spr(i)->id==ewBrang)
13964 {
13965 6460 return true;
13966 }
13967
13968 /*if (bgsfx > 0 && guys.idCount(id) < 2) // count self
13969 stop_sfx(bgsfx);
13970 */
13971 7716 }
13972
13973 6511 return false;
13974 12971 }
13975
13976 2862 void eStalfos::KillWeapon()
13977 {
13978
2/2
✓ Branch 0 taken 2862 times.
✓ Branch 1 taken 811 times.
3673 for(int32_t i=0; i<Ewpns.Count(); i++)
13979 {
13980
4/4
✓ Branch 0 taken 773 times.
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 772 times.
✓ Branch 3 taken 1 times.
811 if(((weapon*)Ewpns.spr(i))->type==misc && Ewpns.spr(i)->id==ewBrang)
13981 {
13982 //only kill this Goriya's boomerang -DD
13983
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(((weapon *)Ewpns.spr(i))->parentid == getUID())
13984 {
13985 1 Ewpns.del(i);
13986 1 }
13987 1 }
13988 811 }
13989
13990
4/4
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 2718 times.
✓ Branch 2 taken 111 times.
✓ Branch 3 taken 33 times.
2862 if(wpn==ewBrang && !Ewpns.idCount(ewBrang))
13991 {
13992 111 stop_sfx(WAV_BRANG);
13993 111 }
13994 2862 }
13995
13996 void eStalfos::break_shield()
13997 {
13998 if(!shield)
13999 return;
14000
14001 flags&=~(inv_front | inv_back | inv_left | inv_right);
14002 shield=false;
14003
14004 if(get_bit(quest_rules,qr_BRKNSHLDTILES))
14005 o_tile=s_tile;
14006 }
14007
14008 176 eKeese::eKeese(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14009 176 {
14010
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 dir=(zc_oldrand()&7)+8;
14011
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 step=0;
14012 88 movestatus=1;
14013
2/4
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 88 times.
88 if (dmisc1 != 1 && dmisc19 > 0)
14014 {
14015 step = dmisc19/100.0;
14016 movestatus = 1;
14017 }
14018
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 if (dmisc1 == 2) movestatus=2;
14019 88 c=0;
14020 88 SIZEflags = d->SIZEflags;
14021
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( !(SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) ) hxofs=2;
14022
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
14023
14024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( !(SIZEflags&guyflagOVERRIDE_HIT_WIDTH) ) hxsz=12;
14025
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
14026
14027
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( !(SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) ) hyofs=4;
14028
1/2
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
88 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14029
14030
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( !(SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) ) hysz=8;
14031
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
14032
14033
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14034 //al_trace("->txsz:%i\n", d->txsz); Verified that this is setting the value. -Z
14035 // al_trace("Enemy txsz:%i\n", txsz);
14036
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14037
14038
14039
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
14040
14041
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
14042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
88 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14043 {
14044 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14045 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14046 }
14047
14048
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
88 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
14049 88 clk4=0;
14050 //nets;
14051 88 dummy_int[1]=0;
14052 88 }
14053
14054 24307 bool eKeese::animate(int32_t index)
14055 {
14056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24307 times.
24307 if(switch_hooked) return enemy::animate(index);
14057
2/4
✓ Branch 0 taken 24307 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24307 times.
24307 if(fallclk||drownclk) return enemy::animate(index);
14058
2/2
✓ Branch 0 taken 1247 times.
✓ Branch 1 taken 23060 times.
24307 if(dying)
14059 1247 return Dead(index);
14060
14061
2/2
✓ Branch 0 taken 22929 times.
✓ Branch 1 taken 131 times.
23060 if(clk==0)
14062 {
14063 131 removearmos(x,y,ffcactivated);
14064 131 }
14065
14066
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23060 times.
23060 if(dmisc1 == 1) //Walk style. 0 is keese, 1 is bat.
14067 {
14068 floater_walk(rate,hrate,dstep/100,(zfix)0,10,dmisc16,dmisc17);
14069 }
14070 else
14071 {
14072
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23060 times.
23060 if (dmisc18) floater_walk(rate,hrate,dstep/100,dmisc18/100.0,-1,dmisc16,dmisc17);
14073 23060 else floater_walk(rate,hrate,dstep/100,dstep/1000,10,dmisc16,dmisc17);
14074 }
14075
14076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23060 times.
23060 if(dmisc2 == e2tKEESETRIB)
14077 {
14078 if(++clk4==(dmisc20>0?dmisc20:256))
14079 {
14080 if(!m_walkflag(x,y,0, dir))
14081 {
14082 int32_t kids = guys.Count();
14083 bool success = false;
14084 int32_t id2=dmisc3;
14085 success = 0 != addenemy((zfix)x,(zfix)y,id2,-24);
14086
14087 if(success)
14088 {
14089 if(itemguy) // Hand down the carried item
14090 {
14091 guycarryingitem = guys.Count()-1;
14092 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
14093 itemguy = false;
14094 }
14095
14096 ((enemy*)guys.spr(kids))->count_enemy = count_enemy;
14097 }
14098
14099 stop_bgsfx(index);
14100 return true;
14101 }
14102 else
14103 {
14104 clk4=0;
14105 }
14106 }
14107 }
14108 // Keese Tribbles stay on the ground, so there's no problem when they transform.
14109
3/4
✓ Branch 0 taken 8834 times.
✓ Branch 1 taken 14226 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8834 times.
23060 else if(get_bit(quest_rules,qr_ENEMIESZAXIS) && !(isSideViewGravity()))
14110 {
14111
1/2
✓ Branch 0 taken 8834 times.
✗ Branch 1 not taken.
8834 if (get_bit(quest_rules,qr_OLD_KEESE_Z_AXIS))
14112 {
14113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8834 times.
8834 if (moveflags & FLAG_USE_FAKE_Z)
14114 {
14115 fakez=int32_t(step/zslongToFix(dstep*100));
14116 // Some variance in keese flight heights when away from Hero
14117 fakez+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-128)/10));
14118
14119 }
14120 else
14121 {
14122 8834 z=int32_t(step/zslongToFix(dstep*100));
14123 // Some variance in keese flight heights when away from Hero
14124
2/2
✓ Branch 0 taken 8310 times.
✓ Branch 1 taken 524 times.
8834 z+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-128)/10));
14125 }
14126 8834 }
14127 else
14128 {
14129 if (moveflags & FLAG_USE_FAKE_Z)
14130 {
14131 fakez=int32_t(step/zslongToFix(dstep*100));
14132 // Some variance in keese flight heights when away from Hero
14133 fakez+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-40)/4));
14134
14135 }
14136 else
14137 {
14138 z=int32_t(step/zslongToFix(dstep*100));
14139 // Some variance in keese flight heights when away from Hero
14140 z+=int32_t(step*zc_max(zfix(0),(distance(x,y,HeroX(),HeroY())-40)/4));
14141 }
14142 }
14143 8834 }
14144
14145 23060 return enemy::animate(index);
14146 24307 }
14147
14148 4685 void eKeese::drawshadow(BITMAP *dest, bool translucent)
14149 {
14150 4685 int32_t tempy=yofs;
14151 4685 flip = 0;
14152 4685 shadowtile = wpnsbuf[spr_shadow].tile+posframe;
14153
14154
2/2
✓ Branch 0 taken 2135 times.
✓ Branch 1 taken 2550 times.
4685 yofs+=zc_min(int32_t(step/zslongToFix(dstep*10)), 8);
14155
1/2
✓ Branch 0 taken 4685 times.
✗ Branch 1 not taken.
4685 if(!get_bit(quest_rules,qr_ENEMIESZAXIS))
14156 {
14157 yofs+=int32_t(step/zslongToFix(dstep*10));
14158 }
14159
14160
4/6
✓ Branch 0 taken 4685 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4685 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4558 times.
✓ Branch 5 taken 127 times.
4685 if(!shadow_overpit(this) && (!get_bit(quest_rules,qr_ENEMIESZAXIS) || step > 0))
14161 4558 enemy::drawshadow(dest, translucent);
14162 4685 yofs=tempy;
14163 4685 }
14164
14165 55991 void eKeese::draw(BITMAP *dest)
14166 {
14167 55991 update_enemy_frame();
14168 55991 enemy::draw(dest);
14169 55991 }
14170
14171 void eWizzrobe::submerge(bool set)
14172 {
14173 if(get_bit(quest_rules,qr_OLD_WIZZROBE_SUBMERGING))
14174 {
14175 hxofs = set?1000:0;
14176 return;
14177 }
14178 if(submerged == set) return;
14179 submerged = set;
14180 if(set)
14181 hxofs+=1000;
14182 else hxofs -= 1000;
14183 }
14184 eWizzrobe::eWizzrobe(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14185 {
14186 hxofs = 0;
14187 submerged = false;
14188 switch(dmisc1)
14189 {
14190 case 0:
14191 submerge(true);
14192 fading=fade_invisible;
14193 // Set clk to just before the 'reappear' threshold
14194 clk=zc_min(clk+(146+zc_max(0,dmisc5))+14,(146+zc_max(0,dmisc5))-1);
14195 break;
14196
14197 default:
14198 dir=(loadside==right)?right:left;
14199 misc=-3;
14200 break;
14201 }
14202
14203 //netst+2880;
14204 charging=false;
14205 firing=false;
14206 fclk=0;
14207 if(!dmisc1) frate=1200+146; //1200 = 20 seconds
14208 SIZEflags = d->SIZEflags;
14209 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && d->txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14210 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
14211 // al_trace("Enemy txsz:%i\n", txsz);
14212 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && d->tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14213 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && d->hxsz >= 0 ) hxsz = d->hxsz;
14214 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && d->hysz >= 0 ) hysz = d->hysz;
14215 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && d->hzsz >= 0 ) hzsz = d->hzsz;
14216 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 )
14217 {
14218 hxofs = (submerged?hxofs:0)+d->hxofs;
14219 }
14220 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14221 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
14222 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
14223 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14224 {
14225 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14226 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14227 }
14228
14229 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
14230 }
14231
14232 bool eWizzrobe::animate(int32_t index)
14233 {
14234 if(switch_hooked) return enemy::animate(index);
14235 if(fallclk||drownclk) return enemy::animate(index);
14236 if(dying)
14237 {
14238 return Dead(index);
14239 }
14240
14241 if(clk==0)
14242 {
14243 removearmos(x,y,ffcactivated);
14244 }
14245
14246 if(dmisc1) // Floating
14247 {
14248 wizzrobe_attack();
14249 }
14250 else // Teleporting
14251 {
14252 if(watch || (!get_bit(quest_rules, qr_WIZZROBES_DONT_OBEY_STUN) && stunclk))
14253 {
14254 fading=0;
14255 submerge(false);
14256 solid_update(false);
14257 }
14258 else switch(clk)
14259 {
14260 case 0:
14261 if(!dmisc2)
14262 {
14263 // Wizzrobe Misc4 controls whether wizzrobes can teleport on top of solid combos,
14264 // but should not appear on dungeon walls.
14265 if ( FFCore.getQuestHeaderInfo(vZelda) <= 0x190 ) place_on_axis(true, false); //1.84, and probably 1.90 wizzrobes should NEVER appear in dungeon walls.-Z (1.84 confirmed, 15th January, 2019 by Chris Miller).
14266 else if (editorflags&ENEMY_FLAG5)
14267 {
14268 //2.10 Windrobe
14269 //randomise location and face Hero
14270 int32_t t=0;
14271 bool placed=false;
14272
14273 while(!placed && t<160)
14274 {
14275 if(isdungeon())
14276 {
14277 x=((zc_oldrand()%12)+2)*16;
14278 y=((zc_oldrand()%7)+2)*16;
14279 }
14280 else
14281 {
14282 x=((zc_oldrand()%14)+1)*16;
14283 y=((zc_oldrand()%9)+1)*16;
14284 }
14285
14286 if(!m_walkflag(x,y,spw_door, dir)&&((abs(x-Hero.getX())>=32)||(abs(y-Hero.getY())>=32)))
14287 {
14288 placed=true;
14289 }
14290
14291 ++t;
14292 }
14293
14294 if(abs(x-Hero.getX())<abs(y-Hero.getY()))
14295 {
14296 if(y<Hero.getY())
14297 {
14298 dir=down;
14299 }
14300 else
14301 {
14302 dir=up;
14303 }
14304 }
14305 else
14306 {
14307 if(x<Hero.getX())
14308 {
14309 dir=right;
14310 }
14311 else
14312 {
14313 dir=left;
14314 }
14315 }
14316
14317 if(!placed) // can't place him, he's gone
14318 return true;
14319
14320
14321 //wizzrobe_attack(); //Complaint about 2.10 Windrobes not behaving as they did in 2.10. Let's try it this way. -Z
14322 //wizzrobe_attack_for_real(); //doing this makes them fire twice. The rest is correct.
14323 }
14324 else place_on_axis(true, dmisc4!=0);
14325 }
14326 else
14327 {
14328 int32_t t=0;
14329 bool placed=false;
14330
14331 while(!placed && t<160)
14332 {
14333 if(isdungeon())
14334 {
14335 x=((zc_oldrand()%12)+2)*16;
14336 y=((zc_oldrand()%7)+2)*16;
14337 }
14338 else
14339 {
14340 x=((zc_oldrand()%14)+1)*16;
14341 y=((zc_oldrand()%9)+1)*16;
14342 }
14343
14344 if(!m_walkflag(x,y,spw_door, dir)&&((abs(x-Hero.getX())>=32)||(abs(y-Hero.getY())>=32)))
14345 {
14346 placed=true;
14347 }
14348
14349 ++t;
14350 }
14351
14352 if(abs(x-Hero.getX())<abs(y-Hero.getY()))
14353 {
14354 if(y<Hero.getY())
14355 {
14356 dir=down;
14357 }
14358 else
14359 {
14360 dir=up;
14361 }
14362 }
14363 else
14364 {
14365 if(x<Hero.getX())
14366 {
14367 dir=right;
14368 }
14369 else
14370 {
14371 dir=left;
14372 }
14373 }
14374
14375 if(!placed) // can't place him, he's gone
14376 return true;
14377 }
14378
14379 fading=fade_flicker;
14380 submerge(false);
14381 solid_update(false);
14382 break;
14383
14384 case 64:
14385 fading=0;
14386 charging=true;
14387 break;
14388
14389 case 73:
14390 charging=false;
14391 firing=40;
14392 break;
14393
14394 case 83:
14395 wizzrobe_attack_for_real();
14396 break;
14397
14398 case 119:
14399 firing=false;
14400 charging=true;
14401 break;
14402
14403 case 128:
14404 fading=fade_flicker;
14405 charging=false;
14406 break;
14407
14408 case 146:
14409 fading=fade_invisible;
14410 submerge(true);
14411 solid_update(false);
14412
14413 [[fallthrough]];
14414 default:
14415 if(clk>=(146+zc_max(0,dmisc5)))
14416 clk=-1;
14417
14418 break;
14419 }
14420 }
14421
14422 return enemy::animate(index);
14423 }
14424
14425 void eWizzrobe::wizzrobe_attack_for_real()
14426 {
14427 if(wpn==0) // Edited enemies
14428 return;
14429
14430 if(dmisc2 == 0) //normal weapon
14431 {
14432 addEwpn(x,y,z,wpn,0,wdp,dir,getUID(), 0, fakez);
14433 sfx(WAV_WAND,pan(int32_t(x)));
14434 }
14435 else if(dmisc2 == 1) // ring of fire
14436 {
14437 addEwpn(x,y,z,wpn,0,wdp,up,getUID(), 0, fakez);
14438 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14439 addEwpn(x,y,z,wpn,0,wdp,down,getUID(), 0, fakez);
14440 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14441 addEwpn(x,y,z,wpn,0,wdp,left,getUID(), 0, fakez);
14442 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14443 addEwpn(x,y,z,wpn,0,wdp,right,getUID(), 0, fakez);
14444 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14445 addEwpn(x,y,z,wpn,0,wdp,l_up,getUID(), 0, fakez);
14446 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14447 addEwpn(x,y,z,wpn,0,wdp,r_up,getUID(), 0, fakez);
14448 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14449 addEwpn(x,y,z,wpn,0,wdp,l_down,getUID(), 0, fakez);
14450 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14451 addEwpn(x,y,z,wpn,0,wdp,r_down,getUID(), 0, fakez);
14452 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
14453 sfx(WAV_FIRE,pan(int32_t(x)));
14454 if (get_bit(quest_rules, qr_8WAY_SHOT_SFX)) sfx(WAV_FIRE,pan(int32_t(x)));
14455 else
14456 {
14457 switch(wpn)
14458 {
14459 case ewFireball: sfx(40,pan(int32_t(x))); break;
14460
14461 case ewArrow: sfx(1,pan(int32_t(x))); break; //Ghost.zh has 0?
14462 case ewBrang: sfx(4,pan(int32_t(x))); break; //Ghost.zh has 0?
14463 case ewSword: sfx(20,pan(int32_t(x))); break; //Ghost.zh has 0?
14464 case ewRock: sfx(51,pan(int32_t(x))); break;
14465 case ewMagic: sfx(32,pan(int32_t(x))); break;
14466 case ewBomb: sfx(3,pan(int32_t(x))); break; //Ghost.zh has 0?
14467 case ewSBomb: sfx(3,pan(int32_t(x))); break; //Ghost.zh has 0?
14468 case ewLitBomb: sfx(21,pan(int32_t(x))); break; //Ghost.zh has 0?
14469 case ewLitSBomb: sfx(21,pan(int32_t(x))); break; //Ghost.zh has 0?
14470 case ewFireTrail: sfx(13,pan(int32_t(x))); break;
14471 case ewFlame: sfx(13,pan(int32_t(x))); break;
14472 case ewWind: sfx(32,pan(int32_t(x))); break;
14473 case ewFlame2: sfx(13,pan(int32_t(x))); break;
14474 case ewFlame2Trail: sfx(13,pan(int32_t(x))); break;
14475 case ewIce: sfx(44,pan(int32_t(x))); break;
14476 case ewFireball2: sfx(40,pan(int32_t(x))); break; //fireball (rising)
14477 default: sfx(WAV_FIRE,pan(int32_t(x))); break;
14478
14479 }
14480 }
14481 }
14482 else if(dmisc2==2) // summons specific enemy
14483 {
14484 int32_t bc=0;
14485
14486 for(int32_t gc=0; gc<guys.Count(); gc++)
14487 {
14488 if((((enemy*)guys.spr(gc))->id) == dmisc3)
14489 {
14490 ++bc;
14491 }
14492 }
14493
14494 if(bc<=40)
14495 {
14496 int32_t kids = guys.Count();
14497 int32_t bats=(zc_oldrand()%3)+1;
14498
14499 for(int32_t i=0; i<bats; i++)
14500 {
14501 // Summon bats (or anything)
14502 if(addchild(x,y,dmisc3,-10, this->script_UID))
14503 ((enemy*)guys.spr(kids+i))->count_enemy = false;
14504 }
14505
14506 sfx(WAV_FIRE,pan(int32_t(x)));
14507 }
14508 }
14509 else if(dmisc2==3) //summon from layer
14510 {
14511 if(count_layer_enemies()==0)
14512 {
14513 return;
14514 }
14515
14516 int32_t kids = guys.Count();
14517
14518 if(kids<200)
14519 {
14520 int32_t newguys=(zc_oldrand()%3)+1;
14521 bool summoned=false;
14522
14523 for(int32_t i=0; i<newguys; i++)
14524 {
14525 int32_t id2=vbound(random_layer_enemy(),eSTART,eMAXGUYS-1);
14526 int32_t x2=0;
14527 int32_t y2=0;
14528
14529 for(int32_t k=0; k<20; ++k)
14530 {
14531 x2=16*((zc_oldrand()%12)+2);
14532 y2=16*((zc_oldrand()%7)+2);
14533
14534 if(!m_walkflag(x2,y2,0, dir) && (abs(x2-Hero.getX())>=32 || abs(y2-Hero.getY())>=32))
14535 {
14536 if(addchild(x2,y2,get_bit(quest_rules,qr_ENEMIESZAXIS) ? 64 : 0,id2,-10, this->script_UID))
14537 {
14538 ((enemy*)guys.spr(kids+i))->count_enemy = false;
14539 if (get_bit(quest_rules,qr_ENEMIESZAXIS) && (((enemy*)guys.spr(kids+i))->moveflags & FLAG_USE_FAKE_Z))
14540 {
14541 ((enemy*)guys.spr(kids+i))->fakez = 64;
14542 ((enemy*)guys.spr(kids+i))->z = 0;
14543 }
14544 }
14545
14546 summoned=true;
14547 break;
14548 }
14549 }
14550 }
14551
14552 if(summoned)
14553 {
14554 sfx(get_bit(quest_rules,qr_MORESOUNDS) ? WAV_ZN1SUMMON : WAV_FIRE,pan(int32_t(x)));
14555 }
14556 }
14557 }
14558 }
14559
14560
14561 void eWizzrobe::wizzrobe_attack()
14562 {
14563 if(clk<0 || dying || stunclk || watch || ceiling || frozenclock)
14564 return;
14565
14566 if(clk3<=0 || ((clk3&31)==0 && !canmove(dir,(zfix)1,spw_door,false) && !misc))
14567 {
14568 fix_coords();
14569
14570 switch(misc)
14571 {
14572 case 1: //walking
14573 if(!m_walkflag(x,y,spw_door, dir))
14574 misc=0;
14575 else
14576 {
14577 clk3=16;
14578
14579 if(!canmove(dir,(zfix)1,spw_wizzrobe,false))
14580 {
14581 wizzrobe_newdir(0);
14582 }
14583 }
14584
14585 break;
14586
14587 case 2: //phasing
14588 {
14589 int32_t jx=x;
14590 int32_t jy=y;
14591 int32_t jdir=-1;
14592
14593 switch(zc_oldrand()&7)
14594 {
14595 case 0:
14596 jx-=32;
14597 jy-=32;
14598 jdir=15;
14599 break;
14600
14601 case 1:
14602 jx+=32;
14603 jy-=32;
14604 jdir=9;
14605 break;
14606
14607 case 2:
14608 jx+=32;
14609 jy+=32;
14610 jdir=11;
14611 break;
14612
14613 case 3:
14614 jx-=32;
14615 jy+=32;
14616 jdir=13;
14617 break;
14618 }
14619
14620 if(jdir>0 && jx>=32 && jx<=208 && jy>=32 && jy<=128)
14621 {
14622 misc=3;
14623 clk3=32;
14624 dir=jdir;
14625 break;
14626 }
14627 }
14628 [[fallthrough]];
14629 case 3:
14630 dir&=3;
14631 misc=0;
14632 [[fallthrough]];
14633 case 0:
14634 wizzrobe_newdir(64);
14635 [[fallthrough]];
14636 default:
14637 if(!canmove(dir,(zfix)1,spw_door,false))
14638 {
14639 if(canmove(dir,(zfix)15,spw_wizzrobe,false))
14640 {
14641 misc=1;
14642 clk3=16;
14643 }
14644 else
14645 {
14646 wizzrobe_newdir(64);
14647 misc=0;
14648 clk3=32;
14649 }
14650 }
14651 else
14652 {
14653 clk3=32;
14654 }
14655
14656 break;
14657 }
14658
14659 if(misc<0)
14660 ++misc;
14661 }
14662
14663 --clk3;
14664
14665 switch(misc)
14666 {
14667 case 1:
14668 case 3:
14669 step=1;
14670 break;
14671
14672 case 2:
14673 step=0;
14674 break;
14675
14676 default:
14677 step=0.5;
14678 break;
14679
14680 }
14681
14682 move(step);
14683
14684 // if(d->misc1 && misc<=0 && clk3==28)
14685 if(dmisc1 && misc<=0 && clk3==28)
14686 {
14687 if(dmisc2 != 1)
14688 {
14689 if(lined_up(8,false) == dir)
14690 {
14691 // addEwpn(x,y,z,wpn,0,wdp,dir,getUID());
14692 // sfx(WAV_WAND,pan(int32_t(x)));
14693 wizzrobe_attack_for_real();
14694 fclk=30;
14695 }
14696 }
14697 else
14698 {
14699 if((zc_oldrand()%500)>=400)
14700 {
14701 wizzrobe_attack_for_real();
14702 fclk=30;
14703 }
14704 }
14705 }
14706
14707 if(misc==0 && (zc_oldrand()&127)==0)
14708 misc=2;
14709
14710 if(misc==2 && clk3==4)
14711 fix_coords();
14712
14713 if(!(charging||firing)) //should never be charging or firing for these wizzrobes
14714 {
14715 if(fclk>0)
14716 {
14717 --fclk;
14718 }
14719 }
14720
14721 }
14722
14723 void eWizzrobe::wizzrobe_newdir(int32_t homing)
14724 {
14725 // Wizzrobes shouldn't move to the edge of the screen;
14726 // if they're already there, they should move toward the center
14727 if(x<32)
14728 dir=right;
14729 else if(x>=224)
14730 dir=left;
14731 else if(y<32)
14732 dir=down;
14733 else if(y>=144)
14734 dir=up;
14735 else
14736 newdir(4,homing,spw_wizzrobe);
14737 }
14738
14739 void eWizzrobe::draw(BITMAP *dest)
14740 {
14741 // if(d->misc1 && (misc==1 || misc==3) && (clk3&1) && hp>0 && !watch && !stunclk) // phasing
14742 if(dmisc1 && (misc==1 || misc==3) && (clk3&1) && hp>0 && !watch && !stunclk && !frozenclock) // phasing
14743 return;
14744
14745 int32_t tempint=dummy_int[1];
14746 bool tempbool1=dummy_bool[1];
14747 bool tempbool2=dummy_bool[2];
14748 dummy_int[1]=fclk;
14749 dummy_bool[1]=charging;
14750 dummy_bool[2]=firing;
14751 update_enemy_frame();
14752 dummy_int[1]=tempint;
14753 dummy_bool[1]=tempbool1;
14754 dummy_bool[2]=tempbool2;
14755 enemy::draw(dest);
14756 }
14757
14758 /*********************************/
14759 /********** Bosses ***********/
14760 /*********************************/
14761
14762 eDodongo::eDodongo(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14763 {
14764 fading=fade_flash_die;
14765 //nets+5120;
14766 if(dir==down&&y>=128)
14767 {
14768 dir=up;
14769 }
14770
14771 if(dir==right&&x>=208)
14772 {
14773 dir=left;
14774 }
14775 SIZEflags = d->SIZEflags;
14776 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14777 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
14778 // al_trace("Enemy txsz:%i\n", txsz);
14779 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14780 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
14781 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
14782 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
14783 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
14784 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14785 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
14786 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
14787 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14788 {
14789 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14790 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14791 }
14792
14793 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
14794 }
14795
14796 bool eDodongo::animate(int32_t index)
14797 {
14798 if(switch_hooked) return enemy::animate(index);
14799 if(dying)
14800 {
14801 return Dead(index);
14802 }
14803
14804 if(clk==0)
14805 {
14806 removearmos(x,y,ffcactivated);
14807 }
14808
14809 if(clk2) // ate a bomb
14810 {
14811 if(--clk2==0)
14812 hp-=misc; // store bomb's power in misc
14813 }
14814 else
14815 constant_walk(rate,homing,spw_clipright);
14816
14817 hxsz = (dir<=down) ? 16 : 32;
14818 // hysz = (dir>=left) ? 16 : 32;
14819
14820 return enemy::animate(index);
14821 }
14822
14823 void eDodongo::draw(BITMAP *dest)
14824 {
14825 tile=o_tile;
14826
14827 if(clk<0)
14828 {
14829 enemy::drawzcboss(dest);
14830 return;
14831 }
14832
14833 update_enemy_frame();
14834 enemy::drawzcboss(dest);
14835
14836 if(dummy_int[1]!=0) //additional tiles
14837 {
14838 tile+=dummy_int[1]; //second tile is previous tile
14839 xofs-=16; //new xofs change
14840 enemy::drawzcboss(dest);
14841 xofs+=16;
14842 }
14843
14844 }
14845
14846 int32_t eDodongo::takehit(weapon *w)
14847 {
14848 int32_t wpnId = w->id;
14849 int32_t power = w->power;
14850 int32_t wpnx = w->x;
14851 int32_t wpny = w->y;
14852
14853 if(dying || clk<0 || clk2>0 || (superman && !(superman>1 && wpnId==wSBomb)))
14854 return 0;
14855
14856 switch(wpnId)
14857 {
14858 case wPhantom:
14859 return 0;
14860
14861 case wFire:
14862 case wBait:
14863 case wWhistle:
14864 case wWind:
14865 case wSSparkle:
14866 case wFSparkle:
14867 return 0;
14868
14869 case wLitBomb:
14870 case wLitSBomb:
14871 if(abs(wpnx-((dir==right)?x+16:x)) > 7 || abs(wpny-y) > 7)
14872 return 0;
14873
14874 clk2=96;
14875 misc=power;
14876
14877 if(wpnId==wLitSBomb)
14878 item_set=isSBOMB100;
14879
14880 return 1;
14881
14882 case wBomb:
14883 case wSBomb:
14884 if(abs(wpnx-((dir==right)?x+16:x)) > 8 || abs(wpny-y) > 8)
14885 return 0;
14886
14887 stunclk=160;
14888 misc=wpnId; // store wpnId
14889 return 1;
14890
14891 case wSword:
14892 if(stunclk)
14893 {
14894 sfx(WAV_EHIT,pan(int32_t(x)));
14895 hp=0;
14896 item_set = (misc==wSBomb) ? isSBOMB100 : isBOMB100;
14897 fading=0; // don't flash
14898 return 1;
14899 }
14900
14901 [[fallthrough]];
14902 default:
14903 sfx(WAV_CHINK,pan(int32_t(x)));
14904 }
14905
14906 return 1;
14907 }
14908
14909 eDodongo2::eDodongo2(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
14910 {
14911 fading=fade_flash_die;
14912 //nets+5180;
14913 previous_dir=-1;
14914 if(dir==down&&y>=128)
14915 {
14916 dir=up;
14917 }
14918
14919 if(dir==right&&x>=208)
14920 {
14921 dir=left;
14922 }
14923 SIZEflags = d->SIZEflags;
14924 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
14925 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
14926 // al_trace("Enemy txsz:%i\n", txsz);
14927 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
14928 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
14929 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
14930 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
14931 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
14932 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
14933 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
14934 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
14935 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
14936 {
14937 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
14938 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
14939 }
14940
14941 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
14942 }
14943
14944 bool eDodongo2::animate(int32_t index)
14945 {
14946 if(switch_hooked) return enemy::animate(index);
14947 if(dying)
14948 {
14949 return Dead(index);
14950 }
14951
14952 if(clk==0)
14953 {
14954 removearmos(x,y,ffcactivated);
14955 }
14956
14957 if(clk2) // ate a bomb
14958 {
14959 if(--clk2==0)
14960 hp-=misc; // store bomb's power in misc
14961 }
14962 else
14963 constant_walk(rate,homing,spw_clipbottomright);
14964
14965 hxsz = (dir<=down) ? 16 : 32;
14966 hysz = (dir>=left) ? 16 : 32;
14967 hxofs=(dir>=left)?-8:0;
14968 hyofs=(dir<left)?-8:0;
14969
14970 return enemy::animate(index);
14971 }
14972
14973 void eDodongo2::draw(BITMAP *dest)
14974 {
14975 if(clk<0)
14976 {
14977 enemy::drawzcboss(dest);
14978 return;
14979 }
14980
14981 int32_t tempx=xofs;
14982 int32_t tempy=yofs;
14983 update_enemy_frame();
14984 enemy::drawzcboss(dest);
14985 tile+=dummy_int[1]; //second tile change
14986 xofs+=dummy_int[2]; //new xofs change
14987 yofs+=dummy_int[3]; //new yofs change
14988 enemy::drawzcboss(dest);
14989 xofs=tempx;
14990 yofs=tempy;
14991 }
14992
14993 int32_t eDodongo2::takehit(weapon *w)
14994 {
14995 int32_t wpnId = w->id;
14996 int32_t power = w->power;
14997 int32_t wpnx = w->x;
14998 int32_t wpny = w->y;
14999
15000 if(dying || clk<0 || clk2>0 || superman)
15001 return 0;
15002
15003 switch(wpnId)
15004 {
15005 case wPhantom:
15006 return 0;
15007
15008 case wFire:
15009 case wBait:
15010 case wWhistle:
15011 case wWind:
15012 case wSSparkle:
15013 case wFSparkle:
15014 return 0;
15015
15016 case wLitBomb:
15017 case wLitSBomb:
15018 switch(dir)
15019 {
15020 case up:
15021 if(abs(wpnx-x) > 7 || abs(wpny-(y-8)) > 7)
15022 return 0;
15023
15024 break;
15025
15026 case down:
15027 if(abs(wpnx-x) > 7 || abs(wpny-(y+8)) > 7)
15028 return 0;
15029
15030 break;
15031
15032 case left:
15033 if(abs(wpnx-(x-8)) > 7 || abs(wpny-y) > 7)
15034 return 0;
15035
15036 break;
15037
15038 case right:
15039 if(abs(wpnx-(x+8)) > 7 || abs(wpny-y) > 7)
15040 return 0;
15041
15042 break;
15043 }
15044
15045 // if(abs(wpnx-((dir==right)?x+8:(dir==left)?x-8:0)) > 7 || abs(wpny-((dir==down)?y+8:(dir==up)?y-8:0)) > 7)
15046 // return 0;
15047 clk2=96;
15048 misc=power;
15049
15050 if(wpnId==wLitSBomb)
15051 item_set=isSBOMB100;
15052
15053 return 1;
15054
15055 case wBomb:
15056 case wSBomb:
15057 switch(dir)
15058 {
15059 case up:
15060 if(abs(wpnx-x) > 7 || abs(wpny-(y-8)) > 7)
15061 return 0;
15062
15063 break;
15064
15065 case down:
15066 if(abs(wpnx-x) > 7 || abs(wpny-(y+8)) > 7)
15067 return 0;
15068
15069 break;
15070
15071 case left:
15072 if(abs(wpnx-(x-8)) > 7 || abs(wpny-y) > 7)
15073 return 0;
15074
15075 break;
15076
15077 case right:
15078 if(abs(wpnx-(x+8)) > 7 || abs(wpny-y) > 7)
15079 return 0;
15080
15081 break;
15082 }
15083
15084 stunclk=160;
15085 misc=wpnId; // store wpnId
15086 return 1;
15087
15088 case wSword:
15089 if(stunclk)
15090 {
15091 sfx(WAV_EHIT,pan(int32_t(x)));
15092 hp=0;
15093 item_set = (misc==wSBomb) ? isSBOMB100 : isBOMB100;
15094 fading=0; // don't flash
15095 return 1;
15096 }
15097
15098 [[fallthrough]];
15099 default:
15100 sfx(WAV_CHINK,pan(int32_t(x)));
15101 }
15102
15103 return 1;
15104 }
15105
15106 4 eAquamentus::eAquamentus(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)//enemy((zfix)176,(zfix)64,Id,Clk)
15107 4 {
15108 //these are here to bypass compiler warnings about unused arguments
15109
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( !(editorflags & ENEMY_FLAG5) )
15110 {
15111
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 x = dmisc1 ? 64 : 176;
15112
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 y = 64;
15113 2 }
15114 else { x = X; y = Y; }
15115
15116 //nets+5940;
15117
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15118 {
15119 1 }
15120 else
15121 {
15122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(dmisc1)
15123 {
15124 flip=1;
15125 }
15126 }
15127
15128
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)+1;
15129 2 clk3=32;
15130 2 clk2=0;
15131 2 clk4=clk;
15132 2 dir=left;
15133 2 SIZEflags = d->SIZEflags;
15134
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15135 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15136 // al_trace("Enemy txsz:%i\n", txsz);
15137
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
15138
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
15139
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
15140
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
15141
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
15142
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
15143 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15144
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
15145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15146 {
15147 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
15148 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15149 }
15150
15151
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
15152 2 }
15153
15154 1101 bool eAquamentus::animate(int32_t index)
15155 {
15156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1101 times.
1101 if(switch_hooked) return enemy::animate(index);
15157
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1065 times.
1101 if(dying)
15158 36 return Dead(index);
15159
15160 // fbx=x+((id==eRAQUAM)?4:-4);
15161
2/2
✓ Branch 0 taken 1060 times.
✓ Branch 1 taken 5 times.
1065 if(clk==0)
15162 {
15163 5 removearmos(x,y,ffcactivated);
15164 5 }
15165
15166 1065 fbx=x;
15167
15168 /*
15169 if (get_bit(quest_rules,qr_NEWENEMYTILES)&&id==eLAQUAM)
15170 {
15171 fbx+=16;
15172 }
15173 */
15174
2/2
✓ Branch 0 taken 1057 times.
✓ Branch 1 taken 8 times.
1065 if(--clk3==0)
15175 {
15176 // addEwpn(fbx,y,z,ewFireball,0,d->wdp,up+1);
15177 // addEwpn(fbx,y,z,ewFireball,0,d->wdp,0);
15178 // addEwpn(fbx,y,z,ewFireball,0,d->wdp,down+1);
15179 8 addEwpn(fbx,y,z,wpn,2,wdp,up,getUID(), 0, fakez);
15180 8 addEwpn(fbx,y,z,wpn,2,wdp,8,getUID(), 0, fakez);
15181 8 addEwpn(fbx,y,z,wpn,2,wdp,down,getUID(), 0, fakez);
15182 8 sfx(wpnsfx(wpn),pan(int32_t(x)));
15183 8 }
15184
15185
4/4
✓ Branch 0 taken 245 times.
✓ Branch 1 taken 820 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 239 times.
1065 if(clk3<-80 && !(zc_oldrand()&63))
15186 {
15187 6 clk3=32;
15188 6 }
15189
15190
2/2
✓ Branch 0 taken 1048 times.
✓ Branch 1 taken 17 times.
1065 if(!((clk4+1)&63))
15191 {
15192 17 int32_t d2=(zc_oldrand()%3)+1;
15193
15194
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 13 times.
17 if(d2>=left)
15195 {
15196 13 dir=d2;
15197 13 }
15198
15199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(dmisc1)
15200 {
15201 if(x<=40)
15202 {
15203 dir=right;
15204 }
15205
15206 if(x>=104)
15207 {
15208 dir=left;
15209 }
15210 }
15211 else
15212 {
15213
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if(x<=136)
15214 {
15215 dir=right;
15216 }
15217
15218
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if(x>=200)
15219 {
15220 dir=left;
15221 }
15222 }
15223 17 }
15224
15225
4/4
✓ Branch 0 taken 1037 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 907 times.
✓ Branch 3 taken 130 times.
1065 if(clk4>=-1 && !((clk4+1)&7))
15226 {
15227
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 64 times.
130 if(dir==left)
15228 {
15229 66 x-=1;
15230 66 }
15231 else
15232 {
15233 64 x+=1;
15234 }
15235 130 }
15236
15237 1065 clk4=(clk4+1)%256;
15238
15239 1065 return enemy::animate(index);
15240 1101 }
15241
15242 1101 void eAquamentus::draw(BITMAP *dest)
15243 {
15244
2/2
✓ Branch 0 taken 414 times.
✓ Branch 1 taken 687 times.
1101 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15245 {
15246 414 xofs=(dmisc1?-16:0);
15247
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 414 times.
✓ Branch 2 taken 193 times.
✓ Branch 3 taken 221 times.
414 if ( do_animation ) tile=o_tile+((clk&24)>>2)+(clk3>-32?(clk3>0?40:80):0);
15248
15249
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 396 times.
414 if(dying)
15250 {
15251 18 xofs=0;
15252 18 enemy::draw(dest);
15253 18 }
15254 else
15255 {
15256 396 drawblock(dest,15);
15257 }
15258 414 }
15259 else
15260 {
15261 687 int32_t xblockofs=((dmisc1)?-16:16);
15262 687 xofs=0;
15263
15264
4/4
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 654 times.
687 if(clk<0 || dying)
15265 {
15266 33 enemy::draw(dest);
15267 33 return;
15268 }
15269
1/2
✓ Branch 0 taken 654 times.
✗ Branch 1 not taken.
654 if ( do_animation )
15270 {
15271 // face (0=firing, 2=resting)
15272 654 tile=o_tile+((clk3>0)?0:2);
15273 654 enemy::draw(dest);
15274 // tail (
15275 654 tile=o_tile+((clk&16)?1:3);
15276 654 xofs=xblockofs;
15277 654 enemy::draw(dest);
15278 // body
15279 654 yofs+=16;
15280 654 xofs=0;
15281 654 tile=o_tile+((clk&16)?20:22);
15282 654 enemy::draw(dest);
15283 654 xofs=xblockofs;
15284 654 tile=o_tile+((clk&16)?21:23);
15285 654 enemy::draw(dest);
15286 654 yofs-=16;
15287 654 }
15288 else enemy::draw(dest);
15289 }
15290 1101 }
15291
15292 335 bool eAquamentus::hit(weapon *w)
15293 {
15294
3/6
✓ Branch 0 taken 335 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 335 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 335 times.
335 if(!(w->scriptcoldet&1) || w->fallclk || w->drownclk) return false;
15295
15296
1/2
✓ Branch 0 taken 335 times.
✗ Branch 1 not taken.
335 switch(w->id)
15297 {
15298 case wBeam:
15299 case wRefBeam:
15300 case wMagic:
15301 335 hysz=32;
15302 335 }
15303
15304
3/4
✓ Branch 0 taken 335 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 20 times.
335 bool ret = (dying || hclk>0) ? false : sprite::hit(w);
15305 335 hysz=16;
15306 335 return ret;
15307
15308 335 }
15309
15310 eGohma::eGohma(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk) // enemy((zfix)128,(zfix)48,Id,0)
15311 {
15312
15313 if ( !(editorflags & ENEMY_FLAG5) )
15314 {
15315 x = 128;
15316 y = 48;
15317 }
15318 else { x = X; y = Y; }
15319
15320 Clk=Clk;
15321 if(flags & guy_fadeflicker)
15322 {
15323 clk=0;
15324 superman = 1;
15325 fading=fade_flicker;
15326 if (!(editorflags&ENEMY_FLAG3)) count_enemy=false;
15327 }
15328 else if(flags & guy_fadeinstant)
15329 {
15330 clk=0;
15331 }
15332 hxofs=-16;
15333 hxsz=48;
15334 clk4=0;
15335 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)+1;
15336 dir=zc_oldrand()%3+1;
15337 SIZEflags = d->SIZEflags;
15338 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15339 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15340 // al_trace("Enemy txsz:%i\n", txsz);
15341 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
15342 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
15343 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
15344 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
15345 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
15346 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
15347 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15348 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
15349 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15350 {
15351 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
15352 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15353 }
15354
15355 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
15356
15357 //nets+5340;
15358 }
15359
15360 bool eGohma::animate(int32_t index)
15361 {
15362 if(switch_hooked) return enemy::animate(index);
15363 if(dying)
15364 return Dead(index);
15365
15366 if(fading)
15367 {
15368 if(++clk4 > 60)
15369 {
15370 clk4=0;
15371 superman=0;
15372 fading=0;
15373 clk=0;
15374
15375 }
15376 else return enemy::animate(index);
15377 }
15378
15379 if(clk==0)
15380 {
15381 if (ffcactivated) removearmosffc(ffcactivated-1);
15382 else
15383 {
15384 removearmos(zc_max(x-16, zfix(0)),y);
15385 did_armos = false;
15386 removearmos(x,y);
15387 did_armos = false;
15388 removearmos(zc_min(x+16, zfix(255)),y);
15389 }
15390 }
15391
15392 if(clk<0) return enemy::animate(index);
15393
15394 // Movement clk must be separate from animation clk because of the Clock item
15395 if(!watch)
15396 clk4++;
15397
15398 if((clk4&63)==0)
15399 {
15400 if(clk4&64)
15401 dir^=1;
15402 else
15403 dir=zc_oldrand()%3+1;
15404 }
15405
15406 if((clk&63)==3)
15407 {
15408 switch(dmisc1)
15409 {
15410 case 1:
15411 addEwpn(x,y+2,z,wpn,3,wdp,left,getUID(), 0, fakez);
15412 addEwpn(x,y+2,z,wpn,3,wdp,8,getUID(), 0, fakez);
15413 addEwpn(x,y+2,z,wpn,3,wdp,right,getUID(), 0, fakez);
15414 sfx(wpnsfx(wpn),pan(int32_t(x)));
15415 break;
15416
15417 default:
15418 if(dmisc1 != 1 && dmisc1 != 2)
15419 {
15420 addEwpn(x,y+2,z,wpn,3,wdp,8,getUID(), 0, fakez);
15421 sfx(wpnsfx(wpn),pan(int32_t(x)));
15422 sfx(wpnsfx(wpn),pan(int32_t(x)));
15423 }
15424
15425 break;
15426 }
15427 }
15428
15429 if((dmisc1 == 2)&& clk3>=16 && clk3<116)
15430 {
15431 if(!(clk3%8))
15432 {
15433 FireBreath(true);
15434 }
15435 }
15436
15437 if(clk4&1)
15438 move((zfix)1);
15439
15440 if(++clk3>=400)
15441 clk3=0;
15442
15443 return enemy::animate(index);
15444 }
15445
15446 void eGohma::draw(BITMAP *dest)
15447 {
15448 tile=o_tile;
15449
15450 if(clk<0 || dying)
15451 {
15452 enemy::drawzcboss(dest);
15453 return;
15454 }
15455
15456 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15457 {
15458 ///if ( do_animation )
15459 //Yuck. Gohma can just not have this capability right now.
15460 // left side
15461 xofs=-16;
15462 flip=0;
15463 // if(clk&16) tile=180;
15464 // else { tile=182; flip=1; }
15465 tile+=(3*((clk&48)>>4));
15466 enemy::drawzcboss(dest);
15467
15468 // right side
15469 xofs=16;
15470 // tile=(180+182)-tile;
15471 tile=o_tile;
15472 tile+=(3*((clk&48)>>4))+2;
15473 enemy::drawzcboss(dest);
15474
15475 // body
15476 xofs=0; //Gohma may need more adjustments for SIZEflags. -Z 14 Aug 2020
15477 tile=o_tile;
15478
15479 // tile+=(3*((clk&24)>>3))+2;
15480 if(clk3<16)
15481 tile+=7;
15482 else if(clk3<116)
15483 tile+=10;
15484 else if(clk3<132)
15485 tile+=7;
15486 else
15487 tile+=((clk3-132)&24)?4:1;
15488
15489 enemy::drawzcboss(dest);
15490
15491 }
15492 else
15493 {
15494 // left side
15495 xofs=-16;
15496 flip=0;
15497
15498 if(!(clk&16))
15499 {
15500 tile+=2;
15501 flip=1;
15502 }
15503
15504 enemy::draw(dest);
15505
15506 // right side
15507 tile=o_tile;
15508 xofs=16;
15509
15510 if((clk&16)) tile+=2;
15511
15512 // tile=(180+182)-tile;
15513 enemy::draw(dest);
15514
15515 // body
15516 tile=o_tile;
15517 xofs=0;
15518
15519 if(clk3<16)
15520 tile+=4;
15521 else if(clk3<116)
15522 tile+=5;
15523 else if(clk3<132)
15524 tile+=4;
15525 else tile+=((clk3-132)&8)?3:1;
15526
15527 enemy::draw(dest);
15528
15529 }
15530 }
15531
15532 int32_t eGohma::takehit(weapon *w)
15533 {
15534 int32_t wpnId = w->id;
15535 int32_t power = w->power;
15536 int32_t wpnx = w->x;
15537 int32_t wpnDir = w->dir;
15538 int32_t def = defenditemclassNew(wpnId, &power, w);
15539
15540 if(def < 0)
15541 {
15542 if(!((wpnDir==up || wpnDir==l_up || wpnDir==r_up) && abs(int32_t(x)-wpnx)<=8 && clk3>=16 && clk3<116))
15543 {
15544 sfx(WAV_CHINK,pan(int32_t(x)));
15545 return 1;
15546 }
15547 }
15548
15549 return enemy::takehit(w);
15550 }
15551
15552 eLilDig::eLilDig(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
15553 {
15554 count_enemy=(id==(id&0xFFF));
15555 //nets+4360+(((id&0xFF)-eDIGPUP2)*40);
15556 SIZEflags = d->SIZEflags;
15557 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15558 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15559 // al_trace("Enemy txsz:%i\n", txsz);
15560 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
15561 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
15562 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
15563 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
15564 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
15565 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
15566 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15567 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
15568 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15569 {
15570 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
15571 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15572 }
15573
15574 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
15575 }
15576
15577 bool eLilDig::animate(int32_t index)
15578 {
15579 if(switch_hooked) return enemy::animate(index);
15580 if(dying)
15581 return Dead(index);
15582
15583 if(clk==0)
15584 {
15585 removearmos(x,y,ffcactivated);
15586 }
15587
15588 if(misc<=128)
15589 {
15590 if(!(++misc&31))
15591 step+=0.25;
15592 }
15593
15594 variable_walk_8(rate,homing,hrate,spw_floater);
15595 return enemy::animate(index);
15596 }
15597
15598 void eLilDig::draw(BITMAP *dest)
15599 {
15600 tile = o_tile;
15601 // tile = 160;
15602 int32_t fdiv = frate/4;
15603 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
15604 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
15605 efrate:((clk>=(frate>>1))?1:0);
15606
15607 if ( do_animation )
15608 {
15609 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15610 {
15611 switch(dir-8) //directions get screwed up after 8. *shrug*
15612 {
15613 case up: //u
15614 flip=0;
15615 break;
15616
15617 case l_up: //d
15618 flip=0;
15619 tile+=4;
15620 break;
15621
15622 case l_down: //l
15623 flip=0;
15624 tile+=8;
15625 break;
15626
15627 case left: //r
15628 flip=0;
15629 tile+=12;
15630 break;
15631
15632 case r_down: //ul
15633 flip=0;
15634 tile+=20;
15635 break;
15636
15637 case down: //ur
15638 flip=0;
15639 tile+=24;
15640 break;
15641
15642 case r_up: //dl
15643 flip=0;
15644 tile+=28;
15645 break;
15646
15647 case right: //dr
15648 flip=0;
15649 tile+=32;
15650 break;
15651 }
15652
15653 tile+=f2;
15654 }
15655 else
15656 {
15657 tile+=(clk>=6)?1:0;
15658 }
15659 }
15660
15661 enemy::draw(dest);
15662 }
15663
15664 eBigDig::eBigDig(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
15665 {
15666 superman=1;
15667
15668 SIZEflags = d->SIZEflags;
15669 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
15670 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
15671 // al_trace("Enemy txsz:%i\n", txsz);
15672 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
15673 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
15674 else hxsz=32;
15675 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
15676 else hysz=32;
15677 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
15678 else hzsz=16; // hard to jump.
15679 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
15680 else hxofs=-8;
15681 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
15682 else hyofs=-8;
15683 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
15684 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
15685 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
15686 {
15687 yofs = d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
15688 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
15689 }
15690
15691 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
15692
15693
15694 }
15695
15696 bool eBigDig::animate(int32_t index)
15697 {
15698 if(switch_hooked) return enemy::animate(index);
15699 if(dying)
15700 return Dead(index);
15701
15702 if(clk==0)
15703 {
15704 removearmos(x,y,ffcactivated);
15705 }
15706
15707 switch(misc)
15708 {
15709 case 0:
15710 variable_walk_8(rate,homing,hrate,spw_floater,-8,-16,23,23);
15711 break;
15712
15713 case 1:
15714 ++misc;
15715 break;
15716
15717 case 2:
15718 for(int32_t i=0; i<dmisc5; i++)
15719 {
15720 addenemy(x,y,dmisc1+0x1000,-15);
15721 }
15722
15723 for(int32_t i=0; i<dmisc6; i++)
15724 {
15725 addenemy(x,y,dmisc2+0x1000,-15);
15726 }
15727
15728 for(int32_t i=0; i<dmisc7; i++)
15729 {
15730 addenemy(x,y,dmisc3+0x1000,-15);
15731 }
15732
15733 for(int32_t i=0; i<dmisc8; i++)
15734 {
15735 addenemy(x,y,dmisc4+0x1000,-15);
15736 }
15737
15738 if(itemguy) // Hand down the carried item
15739 {
15740 guycarryingitem = guys.Count()-1;
15741 ((enemy*)guys.spr(guycarryingitem))->itemguy = true;
15742 itemguy = false;
15743 }
15744
15745 stop_bgsfx(index);
15746
15747 if(deadsfx > 0) sfx(deadsfx,pan(int32_t(x)));
15748
15749 return true;
15750 }
15751
15752 return enemy::animate(index);
15753 }
15754
15755 void eBigDig::draw(BITMAP *dest)
15756 {
15757 if(anim!=aDIG)
15758 {
15759 update_enemy_frame();
15760 xofs-=8;
15761 yofs-=8;
15762 drawblock(dest,15);
15763 xofs+=8;
15764 yofs+=8;
15765 return;
15766 }
15767
15768 tile = o_tile;
15769 int32_t fdiv = frate/4;
15770 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
15771
15772 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
15773 efrate:((clk>=(frate>>1))?1:0);
15774
15775 if ( do_animation )
15776 {
15777 if(get_bit(quest_rules,qr_NEWENEMYTILES))
15778 {
15779 switch(dir-8) //directions get screwed up after 8. *shrug*
15780 {
15781 case up: //u
15782 flip=0;
15783 break;
15784
15785 case l_up: //d
15786 flip=0;
15787 tile+=8;
15788 break;
15789
15790 case l_down: //l
15791 flip=0;
15792 tile+=40;
15793 break;
15794
15795 case left: //r
15796 flip=0;
15797 tile+=48;
15798 break;
15799
15800 case r_down: //ul
15801 flip=0;
15802 tile+=80;
15803 break;
15804
15805 case down: //ur
15806 flip=0;
15807 tile+=88;
15808
15809 break;
15810
15811 case r_up: //dl
15812 flip=0;
15813 tile+=120;
15814 break;
15815
15816 case right: //dr
15817 flip=0;
15818 tile+=128;
15819 break;
15820 }
15821
15822 tile+=(f2*2);
15823 }
15824 else
15825 {
15826 tile+=(f2)?0:2;
15827 flip=(clk&1)?1:0;
15828 }
15829 }
15830
15831 xofs-=8;
15832 yofs-=8;
15833 drawblock(dest,15);
15834 xofs+=8;
15835 yofs+=8;
15836 }
15837
15838 int32_t eBigDig::takehit(weapon *w)
15839 {
15840 int32_t wpnId = w->id;
15841
15842 if(wpnId==wWhistle && misc==0)
15843 misc=1;
15844
15845 return 0;
15846 }
15847
15848 /*
15849 eGanon::eGanon(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
15850 {
15851 hxofs=hyofs=8;
15852 hzsz=16; //can't be jumped.
15853 clk2=70;
15854 misc=-1;
15855 mainguy=!getmapflag();
15856 }
15857
15858 bool eGanon::animate(int32_t index)
15859 {
15860 if(switch_hooked) return enemy::animate(index);
15861 if(dying)
15862
15863 return Dead(index);
15864
15865 if(clk==0)
15866 {
15867 removearmos(x,y,ffcactivated);
15868 }
15869
15870 switch(misc)
15871 {
15872 case -1:
15873 misc=0;
15874
15875 case 0:
15876 if(++clk2>72 && !(zc_oldrand()&3))
15877 {
15878 addEwpn(x,y,z,wpn,3,wdp,dir,getUID());
15879 sfx(wpnsfx(wpn),pan(int32_t(x)));
15880 clk2=0;
15881 }
15882
15883 Stunclk=0;
15884 constant_walk(rate,homing,spw_none);
15885 break;
15886
15887 case 1:
15888 case 2:
15889 if(--Stunclk<=0)
15890 {
15891 int32_t r=zc_oldrand();
15892
15893 if(r&1)
15894 {
15895 y=96;
15896
15897 if(r&2)
15898 x=160;
15899 else
15900 x=48;
15901
15902 if(tooclose(x,y,48))
15903 x=208-x;
15904 }
15905
15906 //if ( editorflags & ENEMY_FLAG15 && current_item_id(itype_amulet,false) >= 2 ) //visible to Amulet 2
15907 //{
15908 // loadpalset(9,pSprite(spBROWN)); //make Ganon visible?
15909 // }
15910 // else
15911 // {
15912 loadpalset(csBOSS,pSprite(d->bosspal));
15913 // }
15914 misc=0;
15915 }
15916
15917 break;
15918
15919 case 3:
15920 {
15921 if(hclk>0)
15922 break;
15923
15924 misc=4;
15925 clk=0;
15926 hxofs=1000;
15927 loadpalset(9,pSprite(spPILE));
15928 music_stop();
15929 stop_sfx(WAV_ROAR);
15930
15931 if(deadsfx>0) sfx(deadsfx,pan(int32_t(x)));
15932
15933 sfx(WAV_GANON);
15934 //Ganon's dustpile; fall in sideview. -Z
15935 item *dustpile = new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0);
15936 dustpile->linked_parent = eeGANON;
15937 setmapflag();
15938 //items.add(new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0));
15939 break;
15940 }
15941
15942 case 4:
15943 if(clk>=80)
15944 {
15945 misc=5;
15946
15947 if(getmapflag())
15948 {
15949 game->lvlitems[dlevel]|=liBOSS;
15950 //play_DmapMusic();
15951 playLevelMusic();
15952 return true;
15953 }
15954
15955 sfx(WAV_CLEARED);
15956 items.add(new item(x+8,y+8,(zfix)0,iBigTri,ipBIGTRI,0));
15957 setmapflag();
15958 }
15959
15960 break;
15961 }
15962
15963 //if ( editorflags & ENEMY_FLAG15 ) //visible to Amulet 2
15964 //{
15965 //if ( current_item_id(itype_amulet,false) >= 2 )
15966 //{
15967 /// loadpalset(9,pSprite(spBROWN)); //make Ganon visible?
15968 //}
15969 //}
15970
15971
15972 return enemy::animate(index);
15973 }
15974
15975
15976 int32_t eGanon::takehit(weapon *w)
15977 {
15978 //these are here to bypass compiler warnings about unused arguments
15979 int32_t wpnId = w->id;
15980 int32_t power = w->power;
15981 int32_t enemyHitWeapon = w->parentitem;
15982
15983 switch(misc)
15984 {
15985 case 0:
15986 {
15987 //if we're not using the editor defences, and Ganon isn't hit by a sword, return.
15988 if(wpnId!=wSword && !(editorflags & ENEMY_FLAG14))
15989 return 0;
15990
15991 //if we are not using the new defences, just reduce his HP
15992 if (!(editorflags & ENEMY_FLAG14))
15993 {
15994 hp-=power;
15995 if(hp>0)
15996 {
15997 misc=1;
15998 Stunclk=64;
15999 }
16000 else
16001 {
16002 loadpalset(csBOSS,pSprite(spBROWN));
16003 misc=2;
16004 Stunclk=284;
16005 hp=guysbuf[id&0xFFF].hp; //16*game->get_hero_dmgmult();
16006 }
16007
16008 sfx(WAV_EHIT,pan(int32_t(x)));
16009
16010 if(hitsfx>0) sfx(hitsfx,pan(int32_t(x)));
16011
16012 return 1;
16013 }
16014 //otherwise, resolve his defence.
16015 else
16016 {
16017 int32_t def = enemy::takehit(w); //This works, but it instantly kills him if it does enough damage.
16018 if(hp>0)
16019 {
16020 misc=1;
16021 Stunclk=64;
16022 }
16023 else
16024 {
16025 loadpalset(csBOSS,pSprite(spBROWN));
16026 misc=2;
16027 Stunclk=284;
16028 hp=guysbuf[id&0xFFF].hp; //16*game->get_hero_dmgmult();
16029 }
16030
16031 sfx(WAV_EHIT,pan(int32_t(x)));
16032
16033 if(hitsfx>0) sfx(hitsfx,pan(int32_t(x)));
16034
16035
16036 return 1;
16037 }
16038 }
16039 case 2:
16040 {
16041 if
16042 (
16043 ( dmisc14 > 0 && !enemyHitWeapon == dmisc14 ) //special weapon needed to kill ganon specified in editor
16044 || //or nothing specified, use silver arrows+
16045 ( dmisc14 <= 0 && (wpnId!=wArrow || (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_arrow))<4))
16046 )
16047 return 0;
16048 {
16049 misc=3;
16050 hclk=81;
16051 loadpalset(9,pSprite(spBROWN));
16052 return 1;
16053 }
16054
16055 }
16056 }
16057
16058 return 0;
16059 }
16060
16061 void eGanon::draw(BITMAP *dest)
16062 {
16063 switch(misc)
16064 {
16065 case 0:
16066 if((clk&3)==3)
16067 tile=(zc_oldrand()%5)*2+o_tile;
16068
16069 if(db!=999)
16070 break;
16071
16072 case 2:
16073 if(Stunclk<64 && (Stunclk&1) )
16074 {
16075 if
16076 (
16077 ( (editorflags & ENEMY_FLAG1) && current_item_power(itype_amulet) >= 2 && (editorflags & ENEMY_FLAG15) )
16078 ||
16079 ( (editorflags & ENEMY_FLAG2) && (game->item[dmisc13]) && (editorflags & ENEMY_FLAG15) )
16080 )
16081 {
16082 goto ganon_draw; //draw his weapons if we can see him
16083 }
16084 break;
16085 }
16086
16087 case -1:
16088 tile=o_tile;
16089
16090 //fall through
16091 case 1:
16092 case 3:
16093 ganon_draw:
16094 drawblock(dest,15);
16095 break;
16096
16097 case 4:
16098 draw_guts(dest);
16099 draw_flash(dest);
16100 break;
16101 }
16102
16103 if ( editorflags & ENEMY_FLAG1 ) //visible to Amulet 2
16104 {
16105 if
16106 (
16107 ( (editorflags & ENEMY_FLAG1) && current_item_power(itype_amulet) >= 2 && (editorflags & ENEMY_FLAG15) )
16108 ||
16109 ( (editorflags & ENEMY_FLAG2) && (game->item[dmisc13]) && (editorflags & ENEMY_FLAG15) )
16110 )
16111 {
16112 draw_guts(dest); //makes his shots visible, but not him
16113 draw_flash(dest);
16114 }
16115 }
16116 }
16117
16118 void eGanon::draw_guts(BITMAP *dest)
16119 {
16120 int32_t c = zc_min(clk>>3,8);
16121 tile = clk<24 ? 74 : 75;
16122 overtile16(dest,tile,x+8,y+c+playing_field_offset,9,0);
16123 overtile16(dest,tile,x+8,y+16-c+playing_field_offset,9,0);
16124 overtile16(dest,tile,x+c,y+8+playing_field_offset,9,0);
16125 overtile16(dest,tile,x+16-c,y+8+playing_field_offset,9,0);
16126 overtile16(dest,tile,x+c,y+c+playing_field_offset,9,0);
16127 overtile16(dest,tile,x+16-c,y+c+playing_field_offset,9,0);
16128 overtile16(dest,tile,x+c,y+16-c+playing_field_offset,9,0);
16129 overtile16(dest,tile,x+16-c,y+16-c+playing_field_offset,9,0);
16130 }
16131
16132 void eGanon::draw_flash(BITMAP *dest)
16133 {
16134
16135 int32_t c = clk-(clk>>2);
16136 cs = (frame&3)+6;
16137 overtile16(dest,194,x+8,y+8-clk+playing_field_offset,cs,0);
16138 overtile16(dest,194,x+8,y+8+clk+playing_field_offset,cs,2);
16139 overtile16(dest,195,x+8-clk,y+8+playing_field_offset,cs,0);
16140 overtile16(dest,195,x+8+clk,y+8+playing_field_offset,cs,1);
16141 overtile16(dest,196,x+8-c,y+8-c+playing_field_offset,cs,0);
16142 overtile16(dest,196,x+8+c,y+8-c+playing_field_offset,cs,1);
16143 overtile16(dest,196,x+8-c,y+8+c+playing_field_offset,cs,2);
16144 overtile16(dest,196,x+8+c,y+8+c+playing_field_offset,cs,3);
16145 }
16146 */
16147
16148 eGanon::eGanon(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
16149 {
16150 hxofs=hyofs=8;
16151 if (editorflags & ENEMY_FLAG3)
16152 {
16153 hxofs = 4;
16154 hyofs = 4;
16155 hxsz = 24;
16156 hysz = 24;
16157 SIZEflags|=guyflagOVERRIDE_HIT_WIDTH;
16158 SIZEflags|=guyflagOVERRIDE_HIT_HEIGHT;
16159 }
16160 hzsz=16; //can't be jumped.
16161 clk2=70;
16162 misc=-1;
16163 mainguy=(!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr->flags9&fBELOWRETURN));
16164 }
16165
16166 bool eGanon::animate(int32_t index) //DO NOT ADD a check for do_animation to this version of GANON!! -Z
16167 {
16168 if(dying)
16169
16170 return Dead(index);
16171
16172 if(clk==0)
16173 {
16174 removearmos(x,y,ffcactivated);
16175 }
16176
16177 switch(misc)
16178 {
16179 case -1:
16180 misc=0;
16181 [[fallthrough]];
16182 case 0:
16183 if(++clk2>72 && !(zc_oldrand()&3))
16184 {
16185 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
16186 sfx(wpnsfx(wpn),pan(int32_t(x)));
16187 clk2=0;
16188 }
16189
16190 Stunclk=0;
16191 constant_walk(rate,homing,spw_none);
16192 break;
16193
16194 case 1:
16195 case 2:
16196 if(--Stunclk<=0)
16197 {
16198 int32_t r=zc_oldrand();
16199
16200 if(r&1)
16201 {
16202 y=96;
16203
16204 if(r&2)
16205 x=160;
16206 else
16207 x=48;
16208
16209 if(tooclose(x,y,48))
16210 x=208-x;
16211 }
16212
16213 loadpalset(csBOSS,pSprite(d->bosspal));
16214 misc=0;
16215 }
16216
16217 break;
16218
16219 case 3:
16220 {
16221 if(hclk>0)
16222 break;
16223
16224 misc=4;
16225 clk=0;
16226 hxofs=1000;
16227 loadpalset(9,pSprite(spPILE));
16228 music_stop();
16229 stop_sfx(WAV_ROAR);
16230
16231 if(deadsfx>0) sfx(deadsfx,pan(int32_t(x)));
16232
16233 sfx(WAV_GANON);
16234 //Ganon's dustpile; fall in sideview. -Z
16235 //item *dustpile = new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0);
16236 //dustpile->miscellaneous[31] = eeGANON;
16237 items.add(new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0));
16238 item *dustpile = NULL;
16239 //dustpile = (item *)items.spr(items.Count() - 1)->getUID();
16240 dustpile = (item *)items.spr(items.Count() - 1);
16241 dustpile->linked_parent = eeGANON; //was miscellaneous[31]
16242 //setmapflag(); //Could be why the Triforce doesn't drop. Disabling this now. -Z ( 6th March, 2019 )
16243 //items.add(new item(x+8,y+8,(zfix)0,iPile,ipDUMMY,0));
16244 break;
16245 }
16246
16247 case 4:
16248 if(clk>=80)
16249 {
16250 misc=5;
16251
16252 //game->lvlitems[dlevel]|=liBOSS;
16253
16254 sfx(WAV_CLEARED);
16255 //Add the big TF over the ashes!
16256 for(word q = 0; q < items.Count(); q++)
16257 {
16258 item *ashes = (item*)items.spr(q);
16259 if ( ashes->linked_parent == eeGANON && (ashes->pickup&ipDUMMY))
16260 {
16261 //Z_scripterrlog("Found correct dustpile!\n");
16262 items.add(new item(ashes->x,ashes->y,(zfix)0,iBigTri,ipBIGTRI,0));
16263 item *bigtriforce = NULL;
16264 bigtriforce = (item *)items.spr(items.Count() - 1);
16265 bigtriforce->linked_parent = eeGANON;
16266 }
16267 }
16268 //setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
16269 //game->lvlitems[dlevel]|=liBOSS; // if we had more rule bits, we could mark him dead so that he does not respawn. -Z
16270 }
16271
16272 break;
16273 case 5: return true;
16274 }
16275
16276 return enemy::animate(index);
16277 }
16278
16279
16280 int32_t eGanon::takehit(weapon *w)
16281 {
16282 //these are here to bypass compiler warnings about unused arguments
16283 int32_t wpnId = w->id;
16284 int32_t power = w->power;
16285 int32_t enemyHitWeapon = w->parentitem;
16286
16287 switch(misc)
16288 {
16289 case 0:
16290 if(wpnId!=wSword)
16291 return 0;
16292
16293 hp-=power;
16294
16295 if(hp>0)
16296 {
16297 misc=1;
16298 Stunclk=64;
16299 }
16300 else
16301 {
16302 loadpalset(csBOSS,pSprite(spBROWN));
16303 misc=2;
16304 Stunclk=284;
16305 hp=guysbuf[id&0xFFF].hp; //16*game->get_hero_dmgmult();
16306 }
16307
16308 sfx(WAV_EHIT,pan(int32_t(x)));
16309
16310 if(hitsfx>0) sfx(hitsfx,pan(int32_t(x)));
16311
16312 return 1;
16313
16314 case 2:
16315 if(wpnId!=wArrow || (enemyHitWeapon>-1 ? itemsbuf[enemyHitWeapon].power : current_item_power(itype_arrow))<4)
16316 return 0;
16317
16318 misc=3;
16319 hclk=81;
16320 loadpalset(9,pSprite(spBROWN));
16321 return 1;
16322 }
16323
16324 return 0;
16325 }
16326
16327 void eGanon::draw(BITMAP *dest)
16328 {
16329 switch(misc)
16330 {
16331 case 0:
16332 if((clk&3)==3)
16333 tile=(zc_oldrand()%5)*2+o_tile;
16334
16335 if ( (editorflags & ENEMY_FLAG1) && current_item_power(itype_amulet) >= 2 ) //ganon is visible to level 2 amulet
16336 {
16337
16338 if ( editorflags & ENEMY_FLAG16 ) //draw cloaked
16339 {
16340 int odraw = drawstyle;
16341 drawstyle = 2;
16342 drawblock(dest,15);
16343 drawstyle = odraw;
16344 }
16345 else
16346 {
16347 drawblock(dest,15);
16348 }
16349 break;
16350
16351 }
16352 else if ( (editorflags & ENEMY_FLAG2) && (game->item[dmisc13]) )
16353 {
16354 if ( editorflags & ENEMY_FLAG16 ) //draw cloaked
16355 {
16356 int odraw = drawstyle;
16357 drawstyle = 2;
16358 drawblock(dest,15);
16359 drawstyle = odraw;
16360 }
16361 else
16362 {
16363 drawblock(dest,15);
16364 }
16365 break;
16366 }
16367 if(db!=999)
16368 break;
16369 [[fallthrough]];
16370 case 2:
16371 if(Stunclk<64 && (Stunclk&1))
16372 break;
16373 [[fallthrough]];
16374 case -1:
16375 tile=o_tile;
16376
16377 [[fallthrough]];
16378 case 1:
16379 case 3:
16380 drawblock(dest,15);
16381 break;
16382
16383 case 4:
16384 draw_guts(dest);
16385 draw_flash(dest);
16386 break;
16387 }
16388 }
16389
16390 void eGanon::draw_guts(BITMAP *dest)
16391 {
16392 int32_t c = zc_min(clk>>3,8);
16393 tile = clk<24 ? 74 : 75;
16394 overtile16(dest,tile,x+8,y+c+playing_field_offset,9,0);
16395 overtile16(dest,tile,x+8,y+16-c+playing_field_offset,9,0);
16396 overtile16(dest,tile,x+c,y+8+playing_field_offset,9,0);
16397 overtile16(dest,tile,x+16-c,y+8+playing_field_offset,9,0);
16398 overtile16(dest,tile,x+c,y+c+playing_field_offset,9,0);
16399 overtile16(dest,tile,x+16-c,y+c+playing_field_offset,9,0);
16400 overtile16(dest,tile,x+c,y+16-c+playing_field_offset,9,0);
16401 overtile16(dest,tile,x+16-c,y+16-c+playing_field_offset,9,0);
16402 }
16403
16404 void eGanon::draw_flash(BITMAP *dest)
16405 {
16406
16407 int32_t c = clk-(clk>>2);
16408 cs = (frame&3)+6;
16409 overtile16(dest,194,x+8,y+8-clk+playing_field_offset,cs,0);
16410 overtile16(dest,194,x+8,y+8+clk+playing_field_offset,cs,2);
16411 overtile16(dest,195,x+8-clk,y+8+playing_field_offset,cs,0);
16412 overtile16(dest,195,x+8+clk,y+8+playing_field_offset,cs,1);
16413 overtile16(dest,196,x+8-c,y+8-c+playing_field_offset,cs,0);
16414 overtile16(dest,196,x+8+c,y+8-c+playing_field_offset,cs,1);
16415 overtile16(dest,196,x+8-c,y+8+c+playing_field_offset,cs,2);
16416 overtile16(dest,196,x+8+c,y+8+c+playing_field_offset,cs,3);
16417 }
16418
16419 void getBigTri(int32_t id2)
16420 {
16421 /*
16422 *************************
16423 * BIG TRIFORCE SEQUENCE *
16424 *************************
16425 0 BIGTRI out, WHITE flash in
16426 4 WHITE flash out, PILE cset white
16427 8 WHITE in
16428 ...
16429 188 WHITE out
16430 191 PILE cset red
16431 200 top SHUTTER opens
16432 209 bottom SHUTTER opens
16433 */
16434 sfx(itemsbuf[id2].playsound);
16435 guys.clear();
16436
16437 if(itemsbuf[id2].flags & ITEM_GAMEDATA)
16438 {
16439 game->lvlitems[dlevel]|=liTRIFORCE;
16440 }
16441
16442 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
16443
16444 draw_screen(tmpscr);
16445
16446 for(int32_t f=0; f<24*8 && !Quit; f++)
16447 {
16448 if(f==4)
16449 {
16450 for(int32_t i=1; i<16; i++)
16451 {
16452 RAMpal[CSET(9)+i]=_RGB(63,63,63);
16453 }
16454 }
16455
16456 if((f&7)==0)
16457 {
16458 for(int32_t cs=2; cs<5; cs++)
16459 {
16460 for(int32_t i=1; i<16; i++)
16461 {
16462 RAMpal[CSET(cs)+i]=_RGB(63,63,63);
16463 }
16464 }
16465
16466 refreshpal=true;
16467 }
16468
16469 if((f&7)==4)
16470 {
16471 if(currscr<128) loadlvlpal(DMaps[currdmap].color);
16472 else loadlvlpal(0xB);
16473 }
16474
16475 if(f==191)
16476 {
16477 loadpalset(9,pSprite(spPILE));
16478 }
16479
16480 advanceframe(true);
16481 }
16482
16483 //play_DmapMusic();
16484 playLevelMusic();
16485
16486 if(itemsbuf[id2].flags & ITEM_FLAG1 && currscr < 128)
16487 {
16488 Hero.dowarp(1,0); //side warp
16489 }
16490 }
16491
16492 /**********************************/
16493 /*** Multiple-Segment Enemies ***/
16494 /**********************************/
16495
16496
16497 //! No. I am not adding SIZEflags to Moldorm and Lanmola. -Z 12 Aug 2020
16498 eMoldorm::eMoldorm(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
16499 {
16500 if( !(editorflags & ENEMY_FLAG5) )
16501 {
16502 x=128;
16503 y=48;
16504 }
16505 //else { x = X; y = Y; }
16506 dir=(zc_oldrand()&7)+8;
16507 superman=1;
16508 fading=fade_invisible;
16509 hxofs=1000;
16510 segcnt=clk;
16511 segid=Id|0x1000;
16512 clk=0;
16513 id=guys.Count();
16514 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
16515 tile=o_tile;
16516 hitdir = -1;
16517 stickclk = 0;
16518
16519 /*
16520 if (get_bit(quest_rules,qr_NEWENEMYTILES))
16521 {
16522 tile=nets+1220;
16523 }
16524 else
16525 {
16526 tile=57;
16527 }
16528 */
16529 }
16530
16531 bool eMoldorm::animate(int32_t index)
16532 {
16533 if(switch_hooked) return enemy::animate(index);
16534 int32_t max_y = isdungeon() ? 100 : 100+28; //warning: Ugly hack. -Z
16535 if ( y > (max_y) )
16536 {
16537 ++stickclk; //Keep Moldorm from pacinn the bottom row or leaving the screen via the bottom edge. -Z 8th Sept, 2019
16538 //Z_scripterrlog("Stickclk is %d\n", stickclk);
16539 }
16540 if ( stickclk > 45 )
16541 {
16542 stickclk = 0;
16543 newdir_8_old(rate,homing,spw_floater); //chage dir to keep from getting stuck.
16544 }
16545
16546
16547 if(clk==0)
16548 {
16549 removearmos(x,y,ffcactivated);
16550 }
16551
16552 if(clk2)
16553 {
16554 if(--clk2 == 0)
16555 {
16556 if(flags&guy_neverret)
16557 never_return(index);
16558
16559 if(!dmisc2 || (editorflags & ENEMY_FLAG6))
16560 leave_item();
16561
16562 stop_bgsfx(index);
16563 return true;
16564 }
16565 }
16566 else
16567 {
16568 if(stunclk>0)
16569 stunclk=0;
16570 constant_walk_8_old(rate,homing,spw_floater);
16571
16572
16573 misc=dir;
16574
16575 // If any higher-numbered segments were killed, segcnt can be too high,
16576 // leading to a crash
16577 if(index+segcnt>=guys.Count())
16578 segcnt=guys.Count()-index-1;
16579
16580 for(int32_t i=index+1; i<index+segcnt+1; i++)
16581 {
16582 enemy* segment=((enemy*)guys.spr(i));
16583
16584 // More validation - if segcnt was wrong, this may not
16585 // actually be a Moldorm segment
16586 if(segment->id!=segid)
16587 {
16588 segcnt=i-index-1;
16589 break;
16590 }
16591
16592 if(i==index+1)
16593 {
16594 x=segment->x;
16595 y=segment->y;
16596 }
16597
16598 segment->o_tile=tile; //I refuse to fuck with adding scripttile to segmented enemies. -Z
16599 //Script your own blasted segmented bosses!! -Z
16600 segment->parent_script_UID = this->script_UID;
16601 if((i==index+segcnt)&&(i!=index+1)) //tail
16602 {
16603 segment->dummy_int[1]=2;
16604 }
16605 else
16606 {
16607 segment->dummy_int[1]=1;
16608 }
16609
16610 if(i==index+1) //head
16611 {
16612 segment->dummy_int[1]=0;
16613 }
16614
16615 if(segment->hp <= 0)
16616 {
16617 int32_t offset=1;
16618
16619 for(int32_t j=i; j<index+segcnt; j++)
16620 {
16621 // Triple-check
16622 if(((enemy*)guys.spr(j+1))->id!=segid)
16623 {
16624 segcnt=j-index+1; // Add 1 because of --segcnt below
16625 break;
16626 }
16627 zc_swap(((enemy*)guys.spr(j))->hp,((enemy*)guys.spr(j+1))->hp);
16628 zc_swap(((enemy*)guys.spr(j))->hclk,((enemy*)guys.spr(j+1))->hclk);
16629 }
16630
16631 segment->hclk=33;
16632 --segcnt;
16633 --i; // Recheck the same index in case multiple segments died at once
16634 }
16635 }
16636
16637 if(segcnt==0)
16638 {
16639 clk2=19;
16640
16641 x=guys.spr(index+1)->x;
16642 y=guys.spr(index+1)->y;
16643 }
16644 }
16645
16646 return false;
16647 }
16648
16649 esMoldorm::esMoldorm(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
16650 {
16651 if( !(editorflags & ENEMY_FLAG5) )
16652 {
16653 x=128;
16654 y=48;
16655 }
16656
16657 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
16658 hyofs=4;
16659 hxsz=hysz=8;
16660 hxofs=1000;
16661 mainguy=count_enemy=false;
16662 parentclk = 0;
16663 bgsfx=-1;
16664 flags&=~guy_neverret;
16665 //deadsfx = WAV_EDEAD;
16666 isCore = false;
16667 }
16668
16669 bool esMoldorm::animate(int32_t index)
16670 {
16671 if(switch_hooked) return enemy::animate(index);
16672 // Shouldn't be possible, but better to be sure
16673 if(index==0)
16674 dying=true;
16675
16676 if(dying)
16677 {
16678 if(!dmisc2)
16679 item_set=0;
16680
16681 return Dead(index);
16682 }
16683
16684 if(clk>=0)
16685 {
16686 hxofs=4;
16687 step=((enemy*)guys.spr(index-1))->step;
16688
16689 if(parentclk == 0)
16690 {
16691 misc=dir;
16692 dir=((enemy*)guys.spr(index-1))->misc;
16693 //do alignment, as in parent's animation :-/ -DD
16694 x.doFloor();
16695 y.doFloor();
16696 }
16697
16698 parentclk=(parentclk+1)%((int32_t)(8.0/step));
16699
16700 if(!watch)
16701 {
16702 sprite::move(step);
16703 }
16704 }
16705
16706 return enemy::animate(index);
16707 }
16708
16709 int32_t esMoldorm::takehit(weapon *w)
16710 {
16711 if(enemy::takehit(w))
16712 return (w->id==wSBomb) ? 1 : 2; // force it to wait a frame before checking sword attacks again
16713
16714 return 0;
16715 }
16716
16717 void esMoldorm::draw(BITMAP *dest)
16718 {
16719 tile=o_tile;
16720 int32_t fdiv = frate/4;
16721 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
16722
16723 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
16724 efrate:((clk>=(frate>>1))?1:0);
16725
16726 if(get_bit(quest_rules,qr_NEWENEMYTILES))
16727 {
16728 tile+=dummy_int[1]*40;
16729
16730 if(dir<8)
16731 {
16732 flip=0;
16733 tile+=4*zc_max(dir, 0); // dir is -1 if trapped
16734
16735 if(dir>3) // Skip to the next row for diagonals
16736 tile+=4;
16737 }
16738 else
16739 {
16740 switch(dir-8) //directions get screwed up after 8. *shrug*
16741 {
16742 case up: //u
16743 flip=0;
16744 break;
16745
16746 case l_up: //d
16747 flip=0;
16748 tile+=4;
16749 break;
16750
16751 case l_down: //l
16752 flip=0;
16753 tile+=8;
16754 break;
16755
16756 case left: //r
16757 flip=0;
16758 tile+=12;
16759 break;
16760
16761 case r_down: //ul
16762 flip=0;
16763 tile+=20;
16764 break;
16765
16766 case down: //ur
16767 flip=0;
16768 tile+=24;
16769 break;
16770
16771 case r_up: //dl
16772 flip=0;
16773 tile+=28;
16774 break;
16775
16776 case right: //dr
16777 flip=0;
16778 tile+=32;
16779 break;
16780 }
16781 }
16782
16783 tile+=f2;
16784 }
16785
16786 if(clk>=0)
16787 enemy::draw(dest);
16788 }
16789
16790 eLanmola::eLanmola(zfix X,zfix Y,int32_t Id,int32_t Clk) : eBaseLanmola(X,Y,Id,Clk)
16791 {
16792 if( !(editorflags & ENEMY_FLAG5) )
16793 {
16794 x=64;
16795 y=80;
16796 }
16797 //else { x = X; y = Y; }
16798 //zprint2("lanmola index is %d\n", index);
16799 //byte legaldirs = 0;
16800 int32_t incr = 16;
16801 //int32_t possiiblepos = 0;
16802 //int32_t positions[8] = {0};
16803
16804 //Don't spawn in pits.
16805 if ( m_walkflag_simple(x, y) )
16806 {
16807 //zprint2("Can't spawn here.\n");
16808 for ( ; incr < 240; incr += 16 )
16809 {
16810 //move if we spawn over a pit
16811 //check each direction
16812 if ( !m_walkflag_simple(x-incr, y) ) //legaldirs |= 0x1; //left
16813 {
16814 //zprint2("Spawn adjustment: -x (%d)\n", incr);
16815 x-=incr; break;
16816 }
16817 else if ( !m_walkflag_simple(x+incr, y) ) //legaldirs |= 0x2; //right
16818 {
16819 //zprint2("Spawn adjustment: +x (%d)\n", incr);
16820 x+=incr; break;
16821 }
16822 else if ( !m_walkflag_simple(x-incr, y-incr) ) //legaldirs |= 0x4; //left-up
16823 {
16824 //zprint2("Spawn adjustment: -x (%d), -y (%d)\n", incr, incr);
16825 x-=incr; y-=incr; break;
16826 }
16827 else if ( !m_walkflag_simple(x+incr, y-incr) ) //legaldirs |= 0x8; //right-up
16828 {
16829 //zprint2("Spawn adjustment: +x (%d), -y (%d)\n", incr, incr);
16830 x+=incr; y-=incr; break;
16831 }
16832 else if ( !m_walkflag_simple(x, y-incr) ) // legaldirs |= 0x10; //up
16833 {
16834 //zprint2("Spawn adjustment: -y (%d)\n", incr);
16835 y -= incr; break;
16836 }
16837 else if ( !m_walkflag_simple(x, y+incr) ) //legaldirs |= 0x20; //down
16838 {
16839 //zprint2("Spawn adjustment: +y (%d)\n", incr);
16840 y+=incr; break;
16841 }
16842 else if ( !m_walkflag_simple(x-incr, y+incr) ) //legaldirs |= 0x40; //left-down
16843 {
16844 //zprint2("Spawn adjustment: -x (%d), +y (%d)\n", incr, incr);
16845 x-=incr; y+=incr; break;
16846 }
16847 else if ( !m_walkflag_simple(x+incr, y+incr) ) //legaldirs |= 0x80; //right-down
16848 {
16849 //zprint2("Spawn adjustment: +x (%d), +y (%d)\n", incr, incr);
16850 x+=incr; y+=incr; break;
16851 }
16852 else continue;
16853
16854 }
16855
16856 }
16857
16858 dir=up;
16859 superman=1;
16860 fading=fade_invisible;
16861 hxofs=1000;
16862 segcnt=clk;
16863 clk=0;
16864 //set up move history
16865 for(int32_t i=0; i <= (1<<dmisc2); i++)
16866 prevState.push_back(std::pair<std::pair<zfix, zfix>, int32_t>(std::pair<zfix,zfix>(x,y), dir));
16867 }
16868
16869 bool eLanmola::animate(int32_t index)
16870 {
16871 if(switch_hooked) return enemy::animate(index);
16872 if(clk==0)
16873 {
16874 removearmos(x,y,ffcactivated);
16875 }
16876
16877 if(clk2)
16878 {
16879 if(--clk2 == 0)
16880 {
16881 if(!dmisc3) //This checks if "segments drop items" isn't true, because if they don't drop items, then only killing the whole thing drops an item.
16882 leave_item();
16883
16884 stop_bgsfx(index);
16885 return true;
16886 }
16887
16888 return false;
16889 }
16890
16891
16892 //this animation style plays ALL KINDS of havoc on the Lanmola segments, since it causes
16893 //the direction AND x,y position of the lanmola to vary in uncertain ways.
16894 //I've added a complete movement history to this enemy to compensate -DD
16895 constant_walk(rate,homing,spw_none);
16896 prevState.pop_front();
16897 prevState.push_front(std::pair<std::pair<zfix, zfix>, int32_t>(std::pair<zfix, zfix>(x,y), dir));
16898
16899 // This could cause a crash with Moldorms. I didn't see the same problem
16900 // with Lanmolas, but it looks like it ought to be possible, so here's
16901 // the same solution. - Saf
16902 if(index+segcnt>=guys.Count())
16903 segcnt=guys.Count()-index-1;
16904
16905 for(int32_t i=index+1; i<index+segcnt+1; i++)
16906 {
16907 enemy* segment=((enemy*)guys.spr(i));
16908
16909 // More validation in case segcnt is wrong
16910 if((segment->id&0xFFF)!=(id&0xFFF))
16911 {
16912 segcnt=i-index-1;
16913 break;
16914 }
16915
16916 segment->o_tile=o_tile;
16917 segment->parent_script_UID = this->script_UID;
16918 if((i==index+segcnt)&&(i!=index+1))
16919 {
16920 segment->dummy_int[1]=1; //tail
16921 }
16922 else
16923 {
16924 segment->dummy_int[1]=0;
16925 }
16926
16927 if(segment->hp <= 0)
16928 {
16929 for(int32_t j=i; j<index+segcnt; j++)
16930 {
16931 // Triple-check
16932 if((((enemy*)guys.spr(j+1))->id&0xFFF)!=(id&0xFFF))
16933 {
16934 segcnt=j-index+1; // Add 1 because of --segcnt below
16935 break;
16936 }
16937 zc_swap(((enemy*)guys.spr(j))->hp,((enemy*)guys.spr(j+1))->hp);
16938 zc_swap(((enemy*)guys.spr(j))->hclk,((enemy*)guys.spr(j+1))->hclk);
16939 }
16940
16941 ((enemy*)guys.spr(i))->hclk=33;
16942 --segcnt;
16943 --i; // Recheck the same index in case multiple segments died at once
16944 }
16945 }
16946
16947 if(segcnt==0)
16948 {
16949 clk2=19;
16950 x=guys.spr(index+1)->x;
16951 y=guys.spr(index+1)->y;
16952 setmapflag(mTMPNORET);
16953 }
16954
16955 //this enemy is invincible.. BUT scripts don't know that, and can "kill" it by setting the hp negative.
16956 //which is... disastrous.
16957 hp = 1;
16958 return enemy::animate(index);
16959 }
16960
16961 esLanmola::esLanmola(zfix X,zfix Y,int32_t Id,int32_t Clk) : eBaseLanmola(X,Y,Id,Clk)
16962 {
16963 if( !(editorflags & ENEMY_FLAG5) )
16964 {
16965 x=64;
16966 y=80;
16967 }
16968 int32_t incr = 16;
16969 //Don't spawn in pits.
16970 if ( m_walkflag_simple(x, y) )
16971 {
16972 //zprint2("Can't spawn here.\n");
16973 for ( ; incr < 240; incr += 16 )
16974 {
16975 //move if we spawn over a pit
16976 //check each direction
16977 if ( !m_walkflag_simple(x-incr, y) ) //legaldirs |= 0x1; //left
16978 {
16979 //zprint2("Spawn adjustment: -x (%d)\n", incr);
16980 x-=incr; break;
16981 }
16982 else if ( !m_walkflag_simple(x+incr, y) ) //legaldirs |= 0x2; //right
16983 {
16984 //zprint2("Spawn adjustment: +x (%d)\n", incr);
16985 x+=incr; break;
16986 }
16987 else if ( !m_walkflag_simple(x-incr, y-incr) ) //legaldirs |= 0x4; //left-up
16988 {
16989 //zprint2("Spawn adjustment: -x (%d), -y (%d)\n", incr, incr);
16990 x-=incr; y-=incr; break;
16991 }
16992 else if ( !m_walkflag_simple(x+incr, y-incr) ) //legaldirs |= 0x8; //right-up
16993 {
16994 //zprint2("Spawn adjustment: +x (%d), -y (%d)\n", incr, incr);
16995 x+=incr; y-=incr; break;
16996 }
16997 else if ( !m_walkflag_simple(x, y-incr) ) // legaldirs |= 0x10; //up
16998 {
16999 //zprint2("Spawn adjustment: -y (%d)\n", incr);
17000 y -= incr; break;
17001 }
17002 else if ( !m_walkflag_simple(x, y+incr) ) //legaldirs |= 0x20; //down
17003 {
17004 //zprint2("Spawn adjustment: +y (%d)\n", incr);
17005 y+=incr; break;
17006 }
17007 else if ( !m_walkflag_simple(x-incr, y+incr) ) //legaldirs |= 0x40; //left-down
17008 {
17009 //zprint2("Spawn adjustment: -x (%d), +y (%d)\n", incr, incr);
17010 x-=incr; y+=incr; break;
17011 }
17012 else if ( !m_walkflag_simple(x+incr, y+incr) ) //legaldirs |= 0x80; //right-down
17013 {
17014 //zprint2("Spawn adjustment: +x (%d), +y (%d)\n", incr, incr);
17015 x+=incr; y+=incr; break;
17016 }
17017 else continue;
17018
17019 }
17020
17021 }
17022
17023 hxofs=1000;
17024 hxsz=8;
17025 mainguy=false;
17026 count_enemy=(id<0x2000)?true:false;
17027
17028 //set up move history
17029 for(int32_t i=0; i <= (1<<dmisc2); i++)
17030 prevState.push_back(std::pair<std::pair<zfix, zfix>, int32_t>(std::pair<zfix,zfix>(x,y), dir));
17031
17032 bgsfx = -1;
17033 isCore = false;
17034 flags&=~guy_neverret;
17035 }
17036
17037 bool esLanmola::animate(int32_t index)
17038 {
17039 if(switch_hooked) return enemy::animate(index);
17040 // Shouldn't be possible, but who knows
17041 if(index==0)
17042 dying=true;
17043
17044 if(dying)
17045 {
17046 xofs=0;
17047
17048 if(!dmisc3)
17049 item_set=0;
17050
17051 return Dead(index);
17052 }
17053
17054 if(clk>=0)
17055 {
17056 hxofs=4;
17057
17058 if(!watch)
17059 {
17060 std::pair<std::pair<zfix, zfix>, int32_t> newstate = ((eBaseLanmola*)guys.spr(index-1))->prevState.front();
17061 prevState.pop_front();
17062 prevState.push_back(newstate);
17063 x = newstate.first.first;
17064 y = newstate.first.second;
17065 dir = newstate.second;
17066 }
17067 }
17068
17069 return enemy::animate(index);
17070 }
17071
17072 int32_t esLanmola::takehit(weapon *w)
17073 {
17074 if(enemy::takehit(w))
17075 return (w->id==wSBomb) ? 1 : 2; // force it to wait a frame before checking sword attacks again
17076
17077 return 0;
17078 }
17079
17080 void esLanmola::draw(BITMAP *dest)
17081 {
17082 tile=o_tile;
17083 int32_t fdiv = frate/4;
17084 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
17085
17086 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
17087 efrate:((clk>=(frate>>1))?1:0);
17088
17089 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17090 {
17091 if(id>=0x2000)
17092 {
17093 tile+=20;
17094
17095 if(dummy_int[1]==1)
17096 {
17097 tile+=20;
17098 }
17099 }
17100
17101 switch(dir)
17102 {
17103 case up:
17104 flip=0;
17105 break;
17106
17107 case down:
17108 flip=0;
17109 tile+=4;
17110 break;
17111
17112 case left:
17113 flip=0;
17114 tile+=8;
17115 break;
17116
17117 case right:
17118 flip=0;
17119 tile+=12;
17120 break;
17121 }
17122
17123 tile+=f2;
17124 }
17125 else
17126 {
17127 if(id>=0x2000)
17128 {
17129 tile+=1;
17130 }
17131 }
17132
17133 if(clk>=0)
17134 enemy::draw(dest);
17135 }
17136
17137 eManhandla::eManhandla(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,0)
17138 {
17139 //these are here to bypass compiler warnings about unused arguments
17140 Clk=Clk;
17141 superman=1;
17142 dir=(zc_oldrand()&7)+8;
17143 armcnt=dmisc2?8:4;//((id==eMANHAN)?4:8);
17144
17145 for(int32_t i=0; i<armcnt; i++)
17146 arm[i]=i;
17147
17148 fading=fade_blue_poof;
17149 //nets+4680;
17150 adjusted=false;
17151 SIZEflags = d->SIZEflags; //Probably will be buggy. -Z 12 AUG 2020
17152 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
17153 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
17154 // al_trace("Enemy txsz:%i\n", txsz);
17155 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
17156 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
17157 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
17158 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
17159 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
17160 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
17161 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
17162 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
17163 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
17164 {
17165 yofs = d->yofs+(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17166 }
17167
17168 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
17169 }
17170
17171 bool eManhandla::animate(int32_t index)
17172 {
17173 if(switch_hooked) return enemy::animate(index);
17174 if(dying)
17175 return Dead(index);
17176
17177 if(clk==0)
17178 {
17179 removearmos(x,y,ffcactivated);
17180 }
17181
17182
17183 // check arm status, move dead ones to end of group
17184 for(int32_t i=0; i<armcnt; i++)
17185 {
17186 enemy* cur_arm = ((enemy*)guys.spr(index+i+1));
17187 if(!cur_arm || cur_arm->dying)
17188 {
17189 for(int32_t j=i; j<armcnt-1; j++)
17190 {
17191 zc_swap(arm[j],arm[j+1]);
17192 guys.swap(index+j+1,index+j+2);
17193 }
17194 if((editorflags & ENEMY_FLAG6)) //They only did this in 2.10
17195 {
17196 leave_item();
17197 }
17198 --armcnt;
17199 --i;
17200 continue;
17201 }
17202 if(!adjusted)
17203 {
17204 if(!dmisc2)
17205 {
17206 cur_arm->o_tile=o_tile+40;
17207 cur_arm->parent_script_UID = this->script_UID;
17208 }
17209 else
17210 {
17211 cur_arm->o_tile=o_tile+160;
17212 cur_arm->parent_script_UID = this->script_UID;
17213 }
17214 }
17215 }
17216
17217 adjusted=true;
17218
17219 // move or die
17220 if(armcnt==0)
17221 hp=0;
17222 else
17223 {
17224 // Speed starts at 0.5, and increases by 0.5 for each head lost. Max speed is 4.5.
17225 step=zc_min(zfix(4.5),(((!dmisc2)?4:8)-int64_t(armcnt))*0.5+zslongToFix(dstep*100));
17226 int32_t dx1=0, dy1=-8, dx2=15, dy2=15;
17227
17228 if(!dmisc2)
17229 {
17230 for(int32_t i=0; i<armcnt; i++)
17231 {
17232 switch(arm[i])
17233 {
17234 case 0:
17235 dy1=-24;
17236 break;
17237
17238 case 1:
17239 dy2=31;
17240 break;
17241
17242 case 2:
17243 dx1=-16;
17244 break;
17245
17246 case 3:
17247 dx2=31;
17248 break;
17249 }
17250 }
17251 }
17252 else
17253 {
17254 dx1=-8, dy1=-16, dx2=23, dy2=23;
17255
17256 for(int32_t i=0; i<armcnt; i++)
17257 {
17258 switch(arm[i]&3)
17259 {
17260 case 0:
17261 dy1=-32;
17262 break;
17263
17264 case 1:
17265 dy2=39;
17266 break;
17267
17268 case 2:
17269 dx1=-24;
17270 break;
17271
17272 case 3:
17273 dx2=39;
17274 break;
17275 }
17276 }
17277 }
17278
17279 variable_walk_8(rate,homing,hrate,spw_floater,dx1,dy1,dx2,dy2);
17280
17281 for(int32_t i=0; i<armcnt; i++)
17282 {
17283 zfix dx=(zfix)0,dy=(zfix)0;
17284
17285 if(!dmisc2)
17286 {
17287 switch(arm[i])
17288 {
17289 case 0:
17290 dy=-16;
17291 break;
17292
17293 case 1:
17294 dy=16;
17295 break;
17296
17297 case 2:
17298 dx=-16;
17299 break;
17300
17301 case 3:
17302 dx=16;
17303 break;
17304 }
17305 }
17306 else
17307 {
17308 switch(arm[i])
17309 {
17310 case 0:
17311 dy=-24;
17312 dx=-8;
17313 break;
17314
17315 case 1:
17316 dy=24;
17317 dx=8;
17318 break;
17319
17320 case 2:
17321 dx=-24;
17322 dy=8;
17323 break;
17324
17325 case 3:
17326 dx=24;
17327 dy=-8;
17328 break;
17329
17330 case 4:
17331 dy=-24;
17332 dx=8;
17333 break;
17334
17335 case 5:
17336 dy=24;
17337 dx=-8;
17338 break;
17339
17340 case 6:
17341 dx=-24;
17342 dy=-8;
17343 break;
17344
17345 case 7:
17346 dx=24;
17347 dy=8;
17348 break;
17349 }
17350 }
17351
17352 guys.spr(index+i+1)->x = x+dx;
17353 guys.spr(index+i+1)->y = y+dy;
17354 }
17355 }
17356
17357 return enemy::animate(index);
17358 }
17359
17360
17361 int32_t eManhandla::takehit(weapon *w)
17362 {
17363 int32_t wpnId = w->id;
17364
17365 if(dying)
17366 return 0;
17367
17368 switch(wpnId)
17369 {
17370 case wBomb:
17371 case wSBomb:
17372 case wSword:
17373 case wHammer:
17374 case wWand:
17375 if (get_bit(quest_rules, qr_MANHANDLA_BLOCK_SFX)) sfx(WAV_EHIT,pan(int32_t(x)));
17376
17377 case wLitBomb:
17378 case wLitSBomb:
17379 case wBait:
17380 case wWhistle:
17381 case wFire:
17382 case wWind:
17383 case wSSparkle:
17384 case wFSparkle:
17385 case wPhantom:
17386 return 0;
17387
17388 case wHookshot:
17389 case wBrang:
17390 sfx(WAV_CHINK,pan(int32_t(x)));
17391 break;
17392
17393 default:
17394 if (get_bit(quest_rules, qr_MANHANDLA_BLOCK_SFX)) sfx(WAV_EHIT,pan(int32_t(x)));
17395 else sfx(WAV_CHINK,pan(int32_t(x)));
17396
17397 }
17398
17399 return 1;
17400 }
17401
17402 void eManhandla::draw(BITMAP *dest)
17403 {
17404 tile=o_tile;
17405 int32_t fdiv = frate/4;
17406 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
17407
17408 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
17409 efrate:((clk>=(frate>>1))?1:0);
17410
17411 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17412 {
17413 if(!dmisc2)
17414 {
17415 switch(dir-8) //directions get screwed up after 8. *shrug*
17416 {
17417 case up: //u
17418 flip=0;
17419 break;
17420
17421 case l_up: //d
17422 flip=0;
17423 tile+=4;
17424 break;
17425
17426 case l_down: //l
17427 flip=0;
17428 tile+=8;
17429 break;
17430
17431 case left: //r
17432 flip=0;
17433 tile+=12;
17434 break;
17435
17436 case r_down: //ul
17437 flip=0;
17438 tile+=20;
17439 break;
17440
17441 case down: //ur
17442 flip=0;
17443 tile+=24;
17444 break;
17445
17446 case r_up: //dl
17447 flip=0;
17448 tile+=28;
17449 break;
17450
17451 case right: //dr
17452 flip=0;
17453 tile+=32;
17454 break;
17455 }
17456
17457 tile+=f2;
17458 enemy::draw(dest);
17459 } //manhandla 2, big body
17460 else
17461 {
17462
17463 switch(dir-8) //directions get screwed up after 8. *shrug*
17464 {
17465 case up: //u
17466 flip=0;
17467 break;
17468
17469 case l_up: //d
17470 flip=0;
17471 tile+=8;
17472 break;
17473
17474 case l_down: //l
17475 flip=0;
17476 tile+=40;
17477 break;
17478
17479 case left: //r
17480 flip=0;
17481 tile+=48;
17482 break;
17483
17484 case r_down: //ul
17485 flip=0;
17486 tile+=80;
17487 break;
17488
17489 case down: //ur
17490 flip=0;
17491 tile+=88;
17492 break;
17493
17494 case r_up: //dl
17495 flip=0;
17496 tile+=120;
17497 break;
17498
17499 case right: //dr
17500 flip=0;
17501 tile+=128;
17502 break;
17503 }
17504
17505 tile+=(f2*2);
17506 xofs-=8;
17507 yofs-=8;
17508 drawblock(dest,15);
17509 xofs+=8;
17510 yofs+=8;
17511 }
17512 }
17513 else
17514 {
17515 if(!dmisc2)
17516 {
17517 enemy::draw(dest);
17518 }
17519 else
17520 {
17521 xofs-=8;
17522 yofs-=8;
17523 enemy::draw(dest);
17524 xofs+=16;
17525 enemy::draw(dest);
17526 yofs+=16;
17527 enemy::draw(dest);
17528 xofs-=16;
17529 enemy::draw(dest);
17530 xofs+=8;
17531 yofs-=8;
17532 }
17533 }
17534 }
17535
17536 esManhandla::esManhandla(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)
17537 {
17538 id=misc=clk;
17539 dir = clk & 3;
17540 clk=0;
17541 mainguy=count_enemy=false;
17542 dummy_bool[0]=false;
17543 item_set=0;
17544 bgsfx=-1;
17545 deadsfx = WAV_EDEAD;
17546 flags &= (~guy_neverret);
17547 isCore = false;
17548 //Probably will be buggy. -Z 12 AUG 2020
17549 SIZEflags = d->SIZEflags;
17550 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
17551 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
17552 // al_trace("Enemy txsz:%i\n", txsz);
17553 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
17554 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
17555 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
17556 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
17557 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
17558 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
17559 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
17560 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = d->xofs;
17561 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
17562 {
17563 yofs = d->yofs+(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17564 }
17565
17566 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = d->zofs;
17567 }
17568
17569 bool esManhandla::animate(int32_t index)
17570 {
17571 if(switch_hooked) return enemy::animate(index);
17572 if(dying)
17573 return Dead(index);
17574
17575 if(clk==0)
17576 {
17577 removearmos(x,y,ffcactivated);
17578 }
17579
17580 if(--clk2<=0)
17581 {
17582 clk2=unsigned(zc_oldrand())%5+5;
17583 clk3^=1;
17584 }
17585
17586 if(!(zc_oldrand()&127))
17587 {
17588 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
17589 sfx(wpnsfx(wpn),pan(int32_t(x)));
17590 }
17591
17592 return enemy::animate(index);
17593 }
17594
17595 void esManhandla::draw(BITMAP *dest)
17596 {
17597 tile=o_tile;
17598 int32_t fdiv = frate/4;
17599 int32_t efrate = fdiv == 0 ? 0 : clk/fdiv;
17600 int32_t f2=get_bit(quest_rules,qr_NEWENEMYTILES)?
17601 efrate:((clk>=(frate>>1))?1:0);
17602
17603 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17604 {
17605 switch(misc&3)
17606 {
17607 case up:
17608 break;
17609
17610 case down:
17611 tile+=4;
17612 break;
17613
17614 case left:
17615 tile+=8;
17616 break;
17617
17618 case right:
17619 tile+=12;
17620 break;
17621 }
17622
17623 tile+=f2;
17624 }
17625 else
17626 {
17627 switch(misc&3)
17628 {
17629 case down:
17630 flip=2;
17631
17632 [[fallthrough]];
17633 case up:
17634 tile=(clk3)?188:189;
17635 break;
17636
17637 case right:
17638 flip=1;
17639 [[fallthrough]];
17640
17641 case left:
17642 tile=(clk3)?186:187;
17643 break;
17644 }
17645 }
17646
17647 enemy::draw(dest);
17648 }
17649
17650 eGleeok::eGleeok(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk) //enemy((zfix)120,(zfix)48,Id,Clk)
17651 {
17652 if ( !(editorflags & ENEMY_FLAG5) )
17653 {
17654 x = 120;
17655 y = 48;
17656 }
17657 else
17658 {
17659 if ( !(editorflags & ENEMY_FLAG6) )
17660 {
17661 x = X; y = Y;
17662 }
17663 else
17664 {
17665 x = X+8; y = Y;
17666 }
17667 }
17668 hzsz = 32; // can't be jumped.
17669 flameclk=0;
17670 misc=clk; // total head count
17671 clk3=clk; // live head count
17672 clk=0;
17673 clk2=60; // fire ball clock
17674 // hp=(guysbuf[eGLEEOK2+(misc-2)].misc2)*(misc-1)*game->get_hero_dmgmult()+guysbuf[eGLEEOK2+(misc-2)].hp;
17675 hp=(guysbuf[id&0xFFF].misc2)*(misc-1)*game->get_hero_dmgmult()+guysbuf[id&0xFFF].hp;
17676 dir = down;
17677 hxofs=4;
17678 hxsz=8;
17679 // frate=17*4;
17680 fading=fade_blue_poof;
17681 //nets+5420;
17682 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17683 {
17684 /*
17685 necktile=o_tile+8;
17686 if (dmisc3)
17687 {
17688 necktile+=8;
17689 }
17690 */
17691 necktile=o_tile+dmisc6;
17692 }
17693 else
17694 {
17695 necktile=s_tile;
17696 }
17697 }
17698
17699 bool eGleeok::animate(int32_t index)
17700 {
17701 if(switch_hooked) return enemy::animate(index);
17702 if(dying)
17703 return Dead(index);
17704
17705 if(clk==0)
17706 {
17707 removearmos(x,y,ffcactivated);
17708 }
17709
17710 // Check if a head was killed somehow...
17711 if(index+1+clk3>=guys.Count())
17712 clk3=guys.Count()-index-1;
17713 if(index+1+misc>=guys.Count())
17714 misc=guys.Count()-index-1;
17715
17716 //fix for the "kill all enemies" item
17717 if(hp==-1000)
17718 {
17719 for(int32_t i=0; i<clk3; ++i)
17720 {
17721 // I haven't seen this fail, but it seems like it ought to be
17722 // possible, so I'm checking for it. - Saf
17723 if((((enemy*)guys.spr(index+i+1))->id&0xFFF)!=(id&0xFFF))
17724 break;
17725 ((enemy*)guys.spr(index+i+1))->hp=1; // re-animate each head,
17726 ((enemy*)guys.spr(index+i+1))->misc = -1; // disconnect it,
17727 ((enemy*)guys.spr(index+i+1))->animate(index+i+1); // let it animate one frame,
17728 ((enemy*)guys.spr(index+i+1))->hp=-1000; // and kill it for good
17729 }
17730
17731 clk3=0;
17732
17733 for(int32_t i=0; i<misc; i++)
17734 {
17735 if((((enemy*)guys.spr(index+i+1))->id&0xFFF)!=(id&0xFFF))
17736 break;
17737 ((enemy*)guys.spr(index+i+1))->misc = -2; // give the signal to disappear
17738 }
17739 }
17740
17741 for(int32_t i=0; i<clk3; i++)
17742 {
17743 enemy *head = ((enemy*)guys.spr(index+i+1));
17744 head->dummy_int[1]=necktile;
17745 head->parent_script_UID = this->script_UID;
17746
17747 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17748 {
17749 head->dummy_int[2]=o_tile+dmisc8; //connected head tile
17750 head->dummy_int[3]=o_tile+dmisc9; //flying head tile
17751 }
17752 else
17753 {
17754 head->dummy_int[2]=necktile+1; //connected head tile
17755 head->dummy_int[3]=necktile+2; //flying head tile
17756 }
17757
17758 head->dmisc5=dmisc5; //neck segments
17759
17760 /*
17761 if (dmisc3)
17762 {
17763 head->dummy_bool[0]=true;
17764 }
17765 */
17766 if(head->hclk)
17767 {
17768 if(hclk==0)
17769 {
17770 hp -= 1000 - head->hp;
17771 hclk = 33;
17772
17773 if(hitsfx>0) sfx(hitsfx,pan(int32_t(head->x)));
17774
17775 sfx(WAV_EHIT,pan(int32_t(head->x)));
17776 }
17777
17778 head->hclk = 0;
17779 }
17780
17781 // Must be set in case of naughty ZScripts
17782 head->hp = 1000;
17783 }
17784
17785 if(hp<=(guysbuf[id&0xFFF].misc2)*(clk3-1)*game->get_hero_dmgmult())
17786 {
17787 ((enemy*)guys.spr(index+clk3))->misc = -1; // give signal to fly off
17788 hp=(guysbuf[id&0xFFF].misc2)*(--clk3)*game->get_hero_dmgmult();
17789 }
17790
17791 if(!dmisc3)
17792 {
17793 if(++clk2>72 && !(zc_oldrand()&3))
17794 {
17795 int32_t i=zc_oldrand()%misc;
17796 enemy *head = ((enemy*)guys.spr(index+i+1));
17797 addEwpn(head->x,head->y,head->z,wpn,3,wdp,dir,getUID(), 0, head->fakez);
17798 sfx(wpnsfx(wpn),pan(int32_t(x)));
17799 clk2=0;
17800 }
17801 }
17802 else
17803 {
17804 if(++clk2>100 && !(zc_oldrand()&3))
17805 {
17806 enemy *head = ((enemy*)guys.spr(zc_oldrand()%misc+index+1));
17807 head->timer=zc_oldrand()%50+50;
17808 clk2=0;
17809 }
17810 }
17811
17812 if((hp<=0 && !immortal))
17813 {
17814 for(int32_t i=0; i<misc; i++)
17815 ((enemy*)guys.spr(index+i+1))->misc = -2; // give the signal to disappear
17816
17817 if(flags&guy_neverret) never_return(index);
17818 }
17819
17820 return enemy::animate(index);
17821 }
17822
17823 int32_t eGleeok::takehit(weapon*)
17824 {
17825 return 0;
17826 }
17827
17828 void eGleeok::draw(BITMAP *dest)
17829 {
17830 tile=o_tile;
17831
17832 if(dying)
17833 {
17834 enemy::draw(dest);
17835 return;
17836 }
17837
17838 int32_t f=clk/17;
17839
17840 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17841 {
17842 // body
17843 xofs=-8;
17844 yofs=32;
17845
17846 switch(f)
17847
17848 {
17849 case 0:
17850 tile+=0;
17851 break;
17852
17853 case 1:
17854 tile+=2;
17855 break;
17856
17857 case 2:
17858 tile+=4;
17859 break;
17860
17861 default:
17862 tile+=6;
17863 break;
17864 }
17865 }
17866 else
17867 {
17868 // body
17869 xofs=-8;
17870 yofs=32;
17871
17872 switch(f)
17873 {
17874 case 0:
17875 tile+=0;
17876 break;
17877
17878 case 2:
17879 tile+=4;
17880 break;
17881
17882 default:
17883 tile+=2;
17884 break;
17885 }
17886 }
17887
17888 enemy::drawblock(dest,15);
17889 }
17890
17891 void eGleeok::draw2(BITMAP *dest)
17892 {
17893 // the neck stub
17894 tile=necktile;
17895 xofs=0;
17896 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17897
17898 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17899 {
17900 tile+=((clk&24)>>3);
17901 }
17902
17903 if(hp > 0 && !dont_draw())
17904 {
17905 if((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))
17906 sprite::drawcloaked(dest);
17907 else
17908 sprite::draw(dest);
17909 }
17910 }
17911
17912 esGleeok::esGleeok(zfix X,zfix Y,int32_t Id,int32_t Clk, sprite * prnt) : enemy(X,Y,Id,Clk), parent(prnt)
17913 {
17914 xoffset=0;
17915 yoffset=(zfix)((dmisc5*4+2));
17916 // dummy_bool[0]=false;
17917 timer=0;
17918 /* fixing */
17919 hp=1000;
17920 step=1;
17921 item_set=0;
17922 //x=120; y=70;
17923 x = xoffset+parent->x;
17924 y = yoffset+parent->y;
17925 hxofs=4;
17926 hxsz=8;
17927 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
17928 clk2=clk; // how int32_t to wait before moving first time
17929 clk=0;
17930 mainguy=count_enemy=false;
17931 dir=zc_oldrand();
17932 clk3=((dir&2)>>1)+2; // left or right
17933 dir&=1; // up or down
17934 dmisc5=vbound(dmisc5,1,255);
17935 isCore = false;
17936 parentCore = parent->getUID();
17937 for(int32_t i=0; i<dmisc5; i++)
17938 {
17939 nxoffset[i] = 0;
17940 nyoffset[i] = 0;
17941 nx[i] = ((((i*(int32_t)x) + (dmisc5-i)*((int32_t)parent->x))) /dmisc5);
17942 ny[i] = ((((i*(int32_t)y) + (dmisc5-i)*((int32_t)parent->y))) /dmisc5);
17943 }
17944
17945 necktile=0;
17946 //TODO compatibility? -DD
17947 /*
17948 for(int32_t i=0; i<4; i++)
17949 {
17950 nx[i]=124;
17951 ny[i]=i*6+48;
17952 }*/
17953 bgsfx=-1;
17954 //no need for deadsfx
17955 }
17956
17957 bool esGleeok::animate(int32_t index)
17958 {
17959 if(switch_hooked) return enemy::animate(index);
17960 // don't call removearmos() - it's a segment.
17961
17962 dmisc5=vbound(dmisc5,1,255);
17963
17964 if(misc == 0)
17965 {
17966 x = (xoffset+parent->x);
17967 y = (yoffset+parent->y);
17968
17969 for(int32_t i=0; i<dmisc5; i++)
17970 {
17971 nx[i] = ((((i*(int32_t)x) + (dmisc5-i)*((int32_t)parent->x))) /dmisc5) + 3 + nxoffset[i];
17972 ny[i] = ((((i*(int32_t)y) + (dmisc5-i)*((int32_t)parent->y))) /dmisc5) + nyoffset[i];
17973 }
17974 }
17975
17976 // set up the head tiles
17977 // headtile=nets+5588; //5580, actually. must adjust for direction later on
17978 /*
17979 if (dummy_bool[0]) //if this is a flame gleeok
17980 {
17981 headtile+=180;
17982 }
17983 */
17984 headtile=dummy_int[2]; //5580, actually. must adjust for direction later on
17985 flyingheadtile=dummy_int[3];
17986
17987 // set up the neck tiles
17988 necktile=dummy_int[1];
17989
17990 if(get_bit(quest_rules,qr_NEWENEMYTILES))
17991 {
17992 necktile+=((clk&24)>>3);
17993 }
17994
17995 /*
17996 else
17997 {
17998 necktile=145;
17999 }
18000 */
18001 // ?((dummy_bool[0])?(nets+4052+(16+((clk&24)>>3))):(nets+4040+(8+((clk&24)>>3)))):145)
18002
18003 switch(misc)
18004 {
18005 case 0: // live head
18006 // set up the attached head tiles
18007 tile=headtile;
18008
18009 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18010 {
18011 tile+=((clk&24)>>3);
18012 /*
18013 if (dummy_bool[0]) {
18014 tile+=1561;
18015 }
18016 */
18017 }
18018
18019 /*
18020 else
18021 {
18022 tile=146;
18023 }
18024 */
18025 if(++clk2>=0 && !(clk2&3))
18026 {
18027 if(y<= (int32_t)parent->y + 8) dir=down;
18028
18029 if(y>= (int32_t)parent->y + dmisc5*8) dir = up;
18030
18031 if(y<= (int32_t)parent->y + 10 && !(zc_oldrand()&31))
18032 {
18033 dir^=1;
18034 }
18035
18036 zfix tempx = x;
18037 zfix tempy = y;
18038
18039 sprite::move(step);
18040 xoffset += (x-tempx);
18041 yoffset += (y-tempy);
18042
18043 if(clk2>=4)
18044 {
18045 clk3^=1;
18046 clk2=-4;
18047 }
18048 else
18049 {
18050 if(x <= (int32_t)parent->x-(dmisc5*6))
18051 {
18052 clk3=right;
18053 }
18054
18055 if(x >= (int32_t)parent->x+(dmisc5*6))
18056 {
18057 clk3=left;
18058 }
18059
18060 if(y <= (int32_t)parent->y+(dmisc5*6) && !(zc_oldrand()&15))
18061 {
18062 clk3^=1; // x jig
18063 }
18064 else
18065 {
18066 if(y<=(int32_t)parent->y+(dmisc5*4) && !(zc_oldrand()&31))
18067 {
18068 clk3^=1; // x switch back
18069 }
18070
18071 clk2=-4;
18072 }
18073 }
18074
18075 zc_swap(dir,clk3);
18076 tempx = x;
18077 tempy = y;
18078 sprite::move(step);
18079 xoffset += (x-tempx);
18080 yoffset += (y-tempy);
18081 zc_swap(dir,clk3);
18082
18083 for(int32_t i=1; i<dmisc5; i++)
18084 {
18085 nxoffset[i] = (zc_oldrand()%3);
18086 nyoffset[i] = (zc_oldrand()%3);
18087 }
18088 }
18089
18090 break;
18091
18092 case 1: // flying head
18093 if(clk>=0)
18094
18095 {
18096 variable_walk_8(rate,homing,hrate,spw_floater);
18097 }
18098
18099 break;
18100
18101 // the following are messages sent from the main guy...
18102 case -1: // got chopped off
18103 {
18104 misc=1;
18105 superman=1;
18106 hxofs=xofs=0;
18107 hxsz=16;
18108 cs=8;
18109 clk=-24;
18110 clk2=40;
18111 dir=(zc_oldrand()&7)+8;
18112 step=8.0/9.0;
18113 }
18114 break;
18115
18116 case -2: // the big guy is dead
18117 return true;
18118 }
18119
18120 if(timer)
18121 {
18122 if(!(timer%8))
18123 {
18124 FireBreath(true);
18125 }
18126
18127 --timer;
18128 }
18129
18130 return enemy::animate(index);
18131 }
18132
18133 int32_t esGleeok::takehit(weapon *w)
18134 {
18135 if ((editorflags & ENEMY_FLAG7) && misc == 1)
18136 {
18137 int32_t wpnId = w->id;
18138
18139 if(dying)
18140 return 0;
18141
18142 switch(wpnId)
18143 {
18144 case wLitBomb:
18145 case wLitSBomb:
18146 case wBait:
18147 case wWhistle:
18148 case wFire:
18149 case wWind:
18150 case wSSparkle:
18151 case wFSparkle:
18152 case wPhantom:
18153 return 0;
18154
18155 case wHookshot:
18156 case wBrang:
18157 case wBeam:
18158 case wArrow:
18159 case wMagic:
18160 case wBomb:
18161 case wSBomb:
18162 sfx(WAV_CHINK,pan(int32_t(x)));
18163 break;
18164 default:
18165 break;
18166 }
18167
18168 return 1;
18169 }
18170 else
18171 {
18172 int32_t ret = enemy::takehit(w);
18173
18174 if(ret==-1)
18175 return 2; // force it to wait a frame before checking sword attacks again
18176
18177 return ret;
18178 }
18179 }
18180
18181 void esGleeok::draw(BITMAP *dest)
18182 {
18183 dmisc5=vbound(dmisc5,1,255);
18184
18185 switch(misc)
18186 {
18187 case 0: //neck
18188 if(!dont_draw())
18189 {
18190 for(int32_t i=1; i<dmisc5; i++) //draw the neck
18191 {
18192 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18193 {
18194 if((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))
18195 overtilecloaked16(dest,necktile+(i*dmisc7),nx[i]-4,ny[i]+playing_field_offset,0);
18196 else
18197 overtile16(dest,necktile+(i*dmisc7),nx[i]-4,ny[i]+playing_field_offset,cs,0);
18198 }
18199 else
18200 {
18201 if((tmpscr->flags3&fINVISROOM)&& !(current_item(itype_amulet)))
18202 overtilecloaked16(dest,necktile,nx[i]-4,ny[i]+playing_field_offset,0);
18203 else
18204 overtile16(dest,necktile,nx[i]-4,ny[i]+playing_field_offset,cs,0);
18205 }
18206 }
18207 }
18208
18209 break;
18210
18211 case 1: //flying head
18212 tile=flyingheadtile;
18213
18214 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18215 {
18216 tile+=((clk&24)>>3);
18217 break;
18218 }
18219
18220 /*
18221 else
18222 {
18223 tile=(clk&1)?147:148;
18224 break;
18225 }
18226 */
18227 }
18228 }
18229
18230 void esGleeok::draw2(BITMAP *dest)
18231 {
18232 enemy::draw(dest);
18233 }
18234
18235 ePatra::ePatra(zfix X,zfix Y,int32_t Id,int32_t Clk) : enemy(X,Y,Id,Clk)// enemy((zfix)128,(zfix)48,Id,Clk)
18236 {
18237 if ( !(editorflags & ENEMY_FLAG5) )
18238 {
18239 x = 128;
18240 y = 48;
18241 }
18242 else { x = X; y = Y; }
18243 adjusted=false;
18244 dir=(zc_oldrand()&7)+8;
18245 //step=0.25;
18246 flycnt=dmisc1;
18247 flycnt2=dmisc2;
18248 loopcnt=0;
18249 clk4 = 0;
18250 clk5 = 0;
18251 clk6 = 0;
18252 clk7 = 0;
18253 if(dmisc6<int16_t(1))dmisc6=1; // ratio cannot be 0!
18254 SIZEflags = d->SIZEflags;
18255 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
18256 else if (dmisc10 == 1) { txsz = 2; extend = 3; }
18257 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
18258 // al_trace("Enemy txsz:%i\n", txsz);
18259 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = tysz; if ( tysz > 1 ) extend = 3; }
18260 else if (dmisc10 == 1) { tysz = 2; extend = 3; }
18261 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = hxsz;
18262 else if (dmisc10 == 1) hxsz = 32;
18263 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = hysz;
18264 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = hzsz;
18265 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = hxofs;
18266 else if (dmisc10 == 1) hxofs = -8;
18267 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = hyofs;
18268 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
18269 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)xofs;
18270 else if (dmisc10 == 1) xofs = -8;
18271 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
18272 {
18273 yofs = (int32_t)yofs; //This seems to be setting to +48 or something with any value set?! -Z
18274 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
18275 }
18276 else if (dmisc10 == 1) yofs = (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset)-8;
18277 if (editorflags & ENEMY_FLAG8) misc = 1;
18278
18279 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)zofs;
18280
18281 if (dmisc29 == 0)
18282 {
18283 if(!dmisc4)
18284 {
18285 if (dmisc10) dmisc29 = (90 / 3);
18286 else dmisc29 = (84 / 3);
18287 }
18288 else
18289 {
18290 if (dmisc10) dmisc29 = (90 / 2);
18291 else dmisc29 = (84 / 2);
18292 }
18293 }
18294 if (dmisc30 == 0)
18295 {
18296 if(!dmisc4)
18297 {
18298 if (dmisc10) dmisc30 = (90 / 3)*0.5;
18299 else dmisc30 = (84 / 3)*0.5;
18300 }
18301 else
18302 {
18303 if (dmisc10) dmisc30 = (90 / 2)*0.5;
18304 else dmisc30 = (84 / 2)*0.5;
18305 }
18306 }
18307 if (dmisc31 == 0)
18308 {
18309 if(!dmisc4)
18310 {
18311 if (dmisc10) dmisc31 = (90 / 3)*2;
18312 else dmisc31 = (84 / 3)*2;
18313 }
18314 else
18315 {
18316 if (dmisc10) dmisc31 = (90 / 2)*0.5;
18317 else dmisc31 = (84 / 2)*0.5;
18318 }
18319 }
18320 if (dmisc32 == 0)
18321 {
18322 if(!dmisc4)
18323 {
18324 if (dmisc10) dmisc32 = (90 / 3);
18325 else dmisc32 = (84 / 3);
18326 }
18327 else
18328 {
18329 if (dmisc10) dmisc32 = (90 / 2)*0.25;
18330 else dmisc32 = (84 / 2)*0.25;
18331 }
18332 }
18333 }
18334
18335 bool ePatra::animate(int32_t index)
18336 {
18337 if(switch_hooked) return enemy::animate(index);
18338 if(dying)
18339 {
18340 for(int32_t i=index+1; i<index+flycnt+flycnt2+1; i++)
18341 {
18342 ((enemy*)guys.spr(i))->hp = -1000;
18343 }
18344
18345 return Dead(index);
18346 }
18347
18348 double basesize = 84;
18349 if (dmisc10) basesize = 90;
18350 double halfsize = basesize / 2;
18351 double quartersize = halfsize / 2;
18352 double twothirdsize = (basesize / 3)*2;
18353 double onethirdsize = (basesize / 3);
18354
18355
18356 if(clk==0)
18357 {
18358 removearmos(x,y,ffcactivated);
18359 }
18360
18361 if ((clk4 <=0 || clk4%2) && (clk7 <= 0 || clk6 <= -16))
18362 {
18363 if (!dmisc22 || loopcnt == 0 || (dmisc22 == 1 && loopcnt < 0)) variable_walk_8(rate,homing,hrate,spw_floater);
18364 if (loopcnt < 0) ++clk2;
18365 if(++clk2>basesize)
18366 {
18367 clk2=0;
18368 if ((!dmisc26 || (dmisc26 == 1 && flycnt) || (dmisc26 == 2 && !flycnt)) && (!(editorflags & ENEMY_FLAG10) || flycnt || flycnt2))
18369 {
18370 if(loopcnt > 0)
18371 --loopcnt;
18372 else if (loopcnt == 0)
18373 {
18374 if((misc%dmisc6)==0)
18375 {
18376 if (dmisc21 > 0) loopcnt=-dmisc21;
18377 else loopcnt=dmisc7;
18378 }
18379 }
18380 else if (loopcnt == -1) loopcnt=dmisc7;
18381 else ++loopcnt;
18382
18383 if (!(editorflags & ENEMY_FLAG9) || loopcnt == 0) ++misc;
18384 }
18385 else
18386 {
18387 loopcnt = 0;
18388 misc = 1;
18389 }
18390 }
18391 }
18392 if (clk4 > 0) --clk4;
18393
18394 double size=1;
18395
18396 if (clk6 < 0)
18397 {
18398 if (dmisc5 == 1 || dmisc5 == 3)
18399 {
18400 if (get_bit(quest_rules,qr_NEWENEMYTILES))
18401 {
18402 if (clk7 <= 0 || clk6 != -16) ++clk6;
18403 if (clk6 == 0) o_tile=d->e_tile;
18404 else
18405 {
18406 if (clk6 >= -16) o_tile=d->e_tile + (IsBigAnim() ? 320 : 80);
18407 else o_tile=d->e_tile + (IsBigAnim() ? 160 : 40);
18408 }
18409 }
18410 else clk6 = 0;
18411 }
18412 }
18413 else if (dmisc19) ++clk6;
18414 if (clk5 < 0) ++clk5;
18415 else if (dmisc19) ++clk5;
18416
18417 if (clk7 > 0 && clk6 >= -16) --clk7;
18418 if (clk6 > 0) clk7 = 0;
18419
18420 for(int32_t i=index+1; i<index+flycnt+1; i++)
18421 {
18422 //outside ring
18423 if(!adjusted)
18424 {
18425 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18426 {
18427 ((enemy*)guys.spr(i))->o_tile=d->e_tile+dmisc8;
18428 enemy *s = ((enemy*)guys.spr(i));
18429 s->parent_script_UID = this->script_UID;
18430 }
18431 else
18432 {
18433 ((enemy*)guys.spr(i))->o_tile=o_tile+1;
18434 enemy *s = ((enemy*)guys.spr(i));
18435 s->parent_script_UID = this->script_UID;
18436 }
18437
18438 ((enemy*)guys.spr(i))->cs=dmisc9;
18439 ((enemy*)guys.spr(i))->hp=dmisc3;
18440 }
18441
18442 if(((enemy*)guys.spr(i))->hp <= 0)
18443 {
18444 for(int32_t j=i; j<index+flycnt+flycnt2; j++)
18445 {
18446 guys.swap(j,j+1);
18447 }
18448
18449 if (--flycnt == 0 && dmisc23 != 0) step += zslongToFix(dmisc23*100);
18450 }
18451 else
18452 {
18453 int32_t pos2 = ((enemy*)guys.spr(i))->misc;
18454 double a2 = (clk2-pos2*(double)basesize/(dmisc1 == 0 ? 1 : dmisc1))*PI/halfsize;
18455
18456 if(!dmisc4) //Big Ring
18457 {
18458 //maybe playing_field_offset here?
18459 if(loopcnt>0)
18460 {
18461 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc31) - zc::math::Sin(pos2*PI*2/(dmisc1 == 0 ? 1 : dmisc1))*((int64_t)abs(dmisc31)-abs(dmisc29));
18462 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc31) + zc::math::Cos(pos2*PI*2/(dmisc1 == 0 ? 1 : dmisc1))*((int64_t)abs(dmisc31)-abs(dmisc29));
18463 }
18464 else
18465 {
18466 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc29);
18467 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc29);
18468 }
18469
18470 temp_x=guys.spr(i)->x;
18471 temp_y=guys.spr(i)->y;
18472 }
18473 else //Oval
18474 {
18475 circle_x = zc::math::Cos(a2+PI/2)*abs(dmisc29);
18476 circle_y = -zc::math::Sin(a2+PI/2)*abs(dmisc29);
18477
18478 if(loopcnt>0)
18479 {
18480 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc29);
18481 guys.spr(i)->y = (-zc::math::Sin(a2+PI/2)-zc::math::Cos(pos2*PI*2/(dmisc1 == 0 ? 1 : dmisc1)))*abs(dmisc31);
18482 }
18483 else
18484 {
18485 guys.spr(i)->x = circle_x;
18486 guys.spr(i)->y = circle_y;
18487 }
18488
18489 temp_x=circle_x;
18490 temp_y=circle_y;
18491 }
18492
18493 double _MSVC2022_tmp1, _MSVC2022_tmp2;
18494 double ddir=atan2_MSVC2022_FIX(double(temp_y),double(temp_x));
18495
18496 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
18497 {
18498 guys.spr(i)->dir=l_down;
18499 }
18500 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
18501 {
18502 guys.spr(i)->dir=left;
18503 }
18504 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
18505 {
18506 guys.spr(i)->dir=l_up;
18507 }
18508 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
18509 {
18510 guys.spr(i)->dir=up;
18511 }
18512 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
18513 {
18514 guys.spr(i)->dir=r_up;
18515 }
18516 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
18517 {
18518 guys.spr(i)->dir=right;
18519 }
18520 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
18521 {
18522 guys.spr(i)->dir=r_down;
18523 }
18524 else
18525 {
18526 guys.spr(i)->dir=down;
18527 }
18528
18529 guys.spr(i)->x += x;
18530 guys.spr(i)->y += y;
18531 }
18532 }
18533
18534 if((wpn>wEnemyWeapons || (wpn >= wScript1 && wpn <= wScript10)) && (dmisc5==1 || dmisc5== 3) && (!dmisc25 || (dmisc25 == 1 && !flycnt && !flycnt2) || (dmisc25 == 2 && (flycnt || flycnt2)) || (dmisc25 == 3 && flycnt2 && !flycnt)))
18535 {
18536 int timeneeded = 48;
18537 int patbreath = (zc_oldrand()%50+50);
18538 if ((patbreath % 4) == 0) ++patbreath;
18539 if (dmisc28 == patratBREATH)
18540 {
18541 timeneeded = 48 + patbreath;
18542 }
18543 if (dmisc28 == patratSTREAM)
18544 {
18545 timeneeded = 48 + 96;
18546 }
18547 if (((((dmisc18 > 0 || ((editorflags & ENEMY_FLAG10) && !flycnt && !flycnt2)) && !(zc_oldrand() % zc_max(dmisc18, 1))) || //New 1/N chance
18548 (dmisc18 == 0 && !(zc_oldrand()&127)) //Old hardcoded firing chance
18549 || (dmisc18 == -1 && loopcnt > 0 && (clk2 == round(halfsize) && (!(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES))
18550 || (clk4 == 10 && (editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)))))
18551 && (clk6 >= 0) //if not in the middle of firing...
18552 && clk6 >= dmisc19) //if over the set cooldown between shots...
18553 && ((!(editorflags & ENEMY_FLAG7) || (loopcnt == 0 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > timeneeded)) || dmisc18 == -1)) //And lastly, if not in danger of starting a loop during the attack.
18554 {
18555 switch(dmisc28)
18556 {
18557 case patratSTREAM:
18558 {
18559 clk7 = 97;
18560 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)) clk6 = -48;
18561 else clk6 = 0;
18562 break;
18563 }
18564 case patratBREATH:
18565 {
18566 clk7 = patbreath;
18567 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)) clk6 = -48;
18568 else clk6 = 0;
18569 break;
18570 }
18571 default:
18572 {
18573 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18574 {
18575 clk6 = -48;
18576 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18577 }
18578 else
18579 {
18580 clk6 = 0;
18581 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18582 FirePatraWeapon();
18583 }
18584 break;
18585 }
18586 } //ew->setAngle(atan2(double(HeroY()-y),double(HeroX()-x)));
18587 }
18588 if (clk6 < 0)
18589 {
18590 switch(dmisc28)
18591 {
18592 case patratSTREAM:
18593 {
18594 if (clk7 > 0 && (clk7 % 12) == 0) FirePatraWeapon();
18595 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18596 break;
18597 }
18598 case patratBREATH:
18599 {
18600 if (clk7 > 0 && (clk7 % 4) == 0) FirePatraWeapon();
18601 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18602 break;
18603 }
18604 default:
18605 {
18606 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) && clk6 == -16)
18607 {
18608 FirePatraWeapon();
18609 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk6) + 16;
18610 }
18611 break;
18612 }
18613 }
18614 }
18615 }
18616
18617 size=.5;
18618 int randattempts = 0;
18619 int randeye = 0;
18620 if (flycnt2 > 0)
18621 {
18622 do
18623 {
18624 randeye = ((flycnt2 > 0) ? (zc_oldrand() % zc_max(1, flycnt2)) : 0);
18625 randeye += (index + flycnt + 1);
18626 ++randattempts;
18627 } while (((esPatra*)guys.spr(randeye))->clk5 < 0 && randattempts < 10);
18628 }
18629 bool dofire = false;
18630 if (dmisc20)
18631 {
18632 if ((dmisc18 > 0 && !(zc_oldrand() % zc_max(dmisc18, 1))) ||
18633 (dmisc18 == 0 && !(zc_oldrand()&127)) ||
18634 (dmisc18 == -1 && (loopcnt > 0 || dmisc20 == 4) && ((clk2 == round(halfsize) && (!(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES)) && dmisc20 != 2 && dmisc20 != 4)
18635 || (clk2 == 10 && dmisc20 != 4 && ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) || dmisc20 == 2))
18636 || ((((((misc%dmisc6) == 0 && (loopcnt == 0 && !dmisc21)) || loopcnt > 1 || loopcnt == -1) && clk2 <= 53 && clk2 >= 51 && (editorflags & ENEMY_FLAG3)) || (!(editorflags & ENEMY_FLAG3) && loopcnt > 0 && clk2 == 1)) && dmisc20 == 4))))
18637 {
18638 if (clk5 >= 0 || !(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES))
18639 {
18640 if (clk5 >= dmisc19)
18641 {
18642 if ((!(editorflags & ENEMY_FLAG7) || (loopcnt == 0 &&
18643 (dmisc20 == 2 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > ((int64_t)48 + (int64_t(12)*flycnt2))) ||
18644 (dmisc20 == 4 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > ((int64_t)48 + 96)) ||
18645 (dmisc20 != 2 && dmisc20 != 4 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > 48)))
18646 || dmisc18 == -1)
18647 dofire = true;
18648 }
18649 }
18650 }
18651 }
18652 if(flycnt2)
18653 {
18654 for(int32_t i=index+flycnt+1; i<index+flycnt+flycnt2+1; i++)//inner ring
18655 {
18656 if(!adjusted)
18657 {
18658 ((enemy*)guys.spr(i))->hp=12*game->get_hero_dmgmult();
18659
18660 if(get_bit(quest_rules,qr_NEWENEMYTILES))
18661 {
18662 if (get_bit(quest_rules,qr_PATRAS_USE_HARDCODED_OFFSETS))
18663 {
18664 switch(dmisc5)
18665 {
18666 // Center eye shoots projectiles; make room for its firing tiles
18667 case 1:
18668 case 3:
18669 ((enemy*)guys.spr(i))->o_tile=d->e_tile+120;
18670 break;
18671
18672 // Center eyes does not shoot; use tiles two rows below for inner eyes.
18673 default:
18674 case 2:
18675 ((enemy*)guys.spr(i))->o_tile=d->e_tile+40;
18676 break;
18677 }
18678 }
18679 else ((enemy*)guys.spr(i))->o_tile = d->s_tile;
18680 }
18681 else
18682 {
18683 ((enemy*)guys.spr(i))->o_tile=o_tile+1;
18684 }
18685
18686 ((enemy*)guys.spr(i))->cs=dmisc9;
18687 if (dmisc27) ((enemy*)guys.spr(i))->hp=dmisc27;
18688 }
18689
18690 if(flycnt>0)
18691 {
18692 ((enemy*)guys.spr(i))->superman=true;
18693 }
18694 else
18695 {
18696 ((enemy*)guys.spr(i))->superman=false;
18697 }
18698
18699 if(((enemy*)guys.spr(i))->hp <= 0)
18700 {
18701 for(int32_t j=i; j<index+flycnt+flycnt2; j++)
18702 {
18703 guys.swap(j,j+1);
18704 }
18705
18706 if (--flycnt2 == 0 && dmisc24 != 0) step += zslongToFix(dmisc24*100);
18707 }
18708 else
18709 {
18710 int32_t pos2 = ((enemy*)guys.spr(i))->misc;
18711 double a2 = ((clk2-pos2*basesize/(dmisc2==0 ? 1 : dmisc2))*PI/(halfsize));
18712
18713 if(dmisc4==0)
18714 {
18715 if(loopcnt>0)
18716 {
18717 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc32) - zc::math::Sin(pos2*PI*2/(dmisc2==0?1:dmisc2))*((int64_t)abs(dmisc32)-abs(dmisc30));
18718 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc32) + zc::math::Cos(pos2*PI*2/(dmisc2==0?1:dmisc2))*((int64_t)abs(dmisc32)-abs(dmisc30));
18719 }
18720 else
18721 {
18722 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc30);
18723 guys.spr(i)->y = -zc::math::Sin(a2+PI/2)*abs(dmisc30);
18724 }
18725
18726 temp_x=guys.spr(i)->x;
18727 temp_y=guys.spr(i)->y;
18728 }
18729 else
18730 {
18731 circle_x = zc::math::Cos(a2+PI/2)*abs(dmisc30);
18732 circle_y = -zc::math::Sin(a2+PI/2)*abs(dmisc30);
18733
18734 if(loopcnt>0)
18735 {
18736 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*abs(dmisc30);
18737 guys.spr(i)->y = (-zc::math::Sin(a2+PI/2)-zc::math::Cos(pos2*PI*2/(dmisc2 == 0 ? 1 : dmisc2)))*abs(dmisc32);
18738 }
18739 else
18740 {
18741 guys.spr(i)->x = circle_x;
18742 guys.spr(i)->y = circle_y;
18743 }
18744
18745 temp_x=circle_x;
18746 temp_y=circle_y;
18747 }
18748
18749 double _MSVC2022_tmp1, _MSVC2022_tmp2;
18750 double ddir=atan2_MSVC2022_FIX(double(temp_y),double(temp_x));
18751
18752 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
18753 {
18754 guys.spr(i)->dir=l_down;
18755 }
18756 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
18757 {
18758 guys.spr(i)->dir=left;
18759 }
18760 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
18761 {
18762 guys.spr(i)->dir=l_up;
18763 }
18764 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
18765 {
18766 guys.spr(i)->dir=up;
18767 }
18768 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
18769 {
18770 guys.spr(i)->dir=r_up;
18771 }
18772 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
18773 {
18774 guys.spr(i)->dir=right;
18775 }
18776 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
18777 {
18778 guys.spr(i)->dir=r_down;
18779 }
18780 else
18781 {
18782 guys.spr(i)->dir=down;
18783 }
18784
18785 guys.spr(i)->x += x;
18786 guys.spr(i)->y = y-guys.spr(i)->y;
18787
18788 if((wpn>wEnemyWeapons || (wpn >= wScript1 && wpn <= wScript10)) && (dmisc5==2 || dmisc5== 3))
18789 {
18790 /*
18791 if(!(zc_oldrand()&127))
18792 {
18793 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID());
18794 sfx(wpnsfx(wpn),pan(int32_t(x)));
18795 }
18796 */
18797 if (((esPatra*)guys.spr(i))->clk5 < 0 && (editorflags & ENEMY_FLAG3))
18798 {
18799 if (((esPatra*)guys.spr(i))->clk4 <= 0 || ((esPatra*)guys.spr(i))->clk5 != -16) ++((esPatra*)guys.spr(i))->clk5;
18800 if (get_bit(quest_rules,qr_PATRAS_USE_HARDCODED_OFFSETS))
18801 {
18802 if (dmisc5 == 3)
18803 {
18804 if (((esPatra*)guys.spr(i))->clk5 >= 0) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+120;
18805 else if (((esPatra*)guys.spr(i))->clk5 >= -16) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+200;
18806 else if (((esPatra*)guys.spr(i))->clk5 >= -48) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+160;
18807 else ((esPatra*)guys.spr(i))->o_tile=d->e_tile+120;
18808 }
18809 else
18810 {
18811 if (((esPatra*)guys.spr(i))->clk5 >= 0) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+40;
18812 else if (((esPatra*)guys.spr(i))->clk5 >= -16) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+120;
18813 else if (((esPatra*)guys.spr(i))->clk5 >= -48) ((esPatra*)guys.spr(i))->o_tile=d->e_tile+80;
18814 else ((esPatra*)guys.spr(i))->o_tile=d->e_tile+40;
18815 }
18816 }
18817 else
18818 {
18819 if (((esPatra*)guys.spr(i))->clk5 >= 0) ((esPatra*)guys.spr(i))->o_tile=d->s_tile;
18820 else if (((esPatra*)guys.spr(i))->clk5 >= -16) ((esPatra*)guys.spr(i))->o_tile=d->s_tile+80;
18821 else if (((esPatra*)guys.spr(i))->clk5 >= -48) ((esPatra*)guys.spr(i))->o_tile=d->s_tile+40;
18822 else ((esPatra*)guys.spr(i))->o_tile=d->s_tile;
18823 }
18824 }
18825 else if ((dmisc19 || ((esPatra*)guys.spr(i))->clk5) && (((esPatra*)guys.spr(i))->clk4 <= 0 || ((esPatra*)guys.spr(i))->clk5 != -16)) ++((esPatra*)guys.spr(i))->clk5;
18826 if (((esPatra*)guys.spr(i))->clk4 > 0) --((esPatra*)guys.spr(i))->clk4;
18827 if (!dmisc25 || (dmisc25 == 1 && !((enemy*)guys.spr(i))->superman) || ((dmisc25 == 2 || dmisc25 == 3) && ((enemy*)guys.spr(i))->superman))
18828 {
18829 switch(dmisc20) //Patra Attack Patterns
18830 {
18831 case 4: //Single one rapidfires
18832 {
18833 if (dofire && i == randeye)
18834 {
18835 ((esPatra*)guys.spr(i))->clk5 = -16;
18836 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES)) ((esPatra*)guys.spr(i))->clk5 = -48;
18837 ((esPatra*)guys.spr(i))->clk4 = 96;
18838 clk5 = -3;
18839 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk5) + 16;
18840 }
18841 if (((esPatra*)guys.spr(i))->clk5 == -16 && (((esPatra*)guys.spr(i))->clk4 % 12) == 0)
18842 {
18843 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18844 sfx(wpnsfx(wpn),pan(int32_t(x)));
18845 }
18846 break;
18847 }
18848 case 3: //Ring
18849 {
18850 if (dofire)
18851 {
18852 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18853 {
18854 ((esPatra*)guys.spr(i))->clk5 = -48;
18855 clk5 = -48;
18856 if (editorflags & ENEMY_FLAG6) clk4 = 64;
18857 }
18858 else
18859 {
18860 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18861 sfx(wpnsfx(wpn),pan(int32_t(x)));
18862 int32_t m=Ewpns.Count()-1;
18863 weapon *ew = (weapon*)(Ewpns.spr(m));
18864
18865 ew->setAngle(atan2(double(HeroY()-y),double(HeroX()-x)));
18866 ((esPatra*)guys.spr(i))->clk5 = 0;
18867 clk5 = 0;
18868 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18869 }
18870 }
18871 if (((esPatra*)guys.spr(i))->clk5 == -16)
18872 {
18873 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18874 sfx(wpnsfx(wpn),pan(int32_t(x)));
18875 int32_t m=Ewpns.Count()-1;
18876 weapon *ew = (weapon*)(Ewpns.spr(m));
18877
18878 ew->setAngle(atan2(double(HeroY()-y),double(HeroX()-x)));
18879 }
18880 break;
18881 }
18882 case 2: //one after another
18883 {
18884 if (dofire)
18885 {
18886 ((esPatra*)guys.spr(i))->clk5 = -48 - (12*(i-(index+flycnt+1)));
18887 clk5 = -48 - (12*flycnt2);
18888 if (editorflags & ENEMY_FLAG6) clk4 = abs(clk5) + 16;
18889 }
18890 if (((esPatra*)guys.spr(i))->clk5 == -16)
18891 {
18892 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18893 sfx(wpnsfx(wpn),pan(int32_t(x)));
18894 }
18895 break;
18896 }
18897 case 1: //random one eye
18898 {
18899 if (dofire && i == randeye)
18900 {
18901 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18902 {
18903 ((esPatra*)guys.spr(i))->clk5 = -48;
18904 clk5 = -48;
18905 if (editorflags & ENEMY_FLAG6) clk4 = 64;
18906 }
18907 else
18908 {
18909 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18910 sfx(wpnsfx(wpn),pan(int32_t(x)));
18911 ((esPatra*)guys.spr(i))->clk5 = 0;
18912 clk5 = 0;
18913 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18914 }
18915 }
18916 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) && ((esPatra*)guys.spr(i))->clk5 == -16)
18917 {
18918 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, guys.spr(i)->fakez);
18919 sfx(wpnsfx(wpn),pan(int32_t(x)));
18920 }
18921 break;
18922 }
18923 default: //old behavior, all eyes can fire any time
18924 {
18925 if ((((dmisc18 && !(zc_oldrand() % zc_max(dmisc18, 1))) ||
18926 (!dmisc18 && !(zc_oldrand()&127))) && (((esPatra*)guys.spr(i))->clk5 >= 0 || !(editorflags & ENEMY_FLAG3) || !get_bit(quest_rules,qr_NEWENEMYTILES))
18927 && ((esPatra*)guys.spr(i))->clk5 >= dmisc19) && (!(editorflags & ENEMY_FLAG7) || (loopcnt == 0 &&
18928 (dmisc20 != 2 && (basesize*((int64_t)dmisc6 - (misc%dmisc6))) > 48))))
18929 {
18930 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES))
18931 {
18932 ((esPatra*)guys.spr(i))->clk5 = -48;
18933 if (editorflags & ENEMY_FLAG6) clk4 = 64;
18934 }
18935 else
18936 {
18937 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, fakez);
18938 sfx(wpnsfx(wpn),pan(int32_t(x)));
18939 ((esPatra*)guys.spr(i))->clk5 = 0;
18940 if (editorflags & ENEMY_FLAG6) clk4 = 16;
18941 }
18942 }
18943 if ((editorflags & ENEMY_FLAG3) && get_bit(quest_rules,qr_NEWENEMYTILES) && ((esPatra*)guys.spr(i))->clk5 == -16)
18944 {
18945 addEwpn(guys.spr(i)->x,guys.spr(i)->y,guys.spr(i)->z,wpn,3,wdp,dir,getUID(), 0, fakez);
18946 sfx(wpnsfx(wpn),pan(int32_t(x)));
18947 }
18948 break;
18949 }
18950 }
18951 }
18952 }
18953
18954 }
18955 }
18956 }
18957
18958 adjusted=true;
18959 return enemy::animate(index);
18960 }
18961
18962 void ePatra::FirePatraWeapon()
18963 { //.707
18964 int32_t xoff = 0;
18965 int32_t yoff = 0;
18966 if ( SIZEflags&guyflagOVERRIDE_HIT_WIDTH )
18967 {
18968 xoff += (hxsz/2)-8;
18969 //Z_scripterrlog("width flag enabled. xoff = %d\n", xoff);
18970 }
18971 if ( SIZEflags&guyflagOVERRIDE_HIT_HEIGHT )
18972 {
18973 yoff += (hysz/2)-8;
18974 //Z_scripterrlog("width flag enabled. yoff = %d\n", yoff);
18975 }
18976 sfx(wpnsfx(wpn),pan(int32_t(x)));
18977 switch (dmisc28)
18978 {
18979 case patrat8SHOT: //Fire Wizzrobe
18980 case patrat4SHOTDIAG:
18981 case patrat4SHOTRAND:
18982 if (dmisc28 != patrat4SHOTRAND || (zc_oldrand()%2)) //if it's the 4 shot rand type, only let it through half the time. Break is within so it doesn't do both, but if it skips this one it'll always do the other one.
18983 {
18984 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,l_up,-1, getUID(),false));
18985 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18986 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18987 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18988
18989 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,l_down,-1, getUID(),false));
18990 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18991 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18992 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18993
18994 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,r_up,-1, getUID(),false));
18995 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
18996 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
18997 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
18998
18999 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,r_down,-1, getUID(),false));
19000 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19001 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19002 if (wpn != ewFlame && wpn != ewFlame2) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= .707; //Fire already does this internall for asome bizarre reason.
19003
19004 if (dmisc28 == patrat4SHOTDIAG || dmisc28 == patrat4SHOTRAND) break;
19005 }
19006
19007 [[fallthrough]];
19008 case patrat4SHOTCARD: //Stalfos 3
19009 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,up,-1, getUID(),false));
19010 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19011 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19012 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,down,-1, getUID(),false));
19013 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19014 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19015 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,left,-1, getUID(),false));
19016 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19017 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19018 Ewpns.add(new weapon(x+xoff,y+yoff,z,wpn,1,wdp,right,-1, getUID(),false));
19019 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19020 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->moveflags &= ~FLAG_CAN_PITFALL; //No falling in pits
19021 break;
19022
19023 default:
19024 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19025 if (dmisc28 == patratBREATH) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle += (zc_rand(20,-20)/100.0)*PI;
19026 double anglestore = ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle;
19027 if (dmisc28 == patrat1SHOTFAST || dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19028 if (dmisc28 == patrat3SHOT || dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOT || dmisc28 == patrat5SHOTFAST)
19029 {
19030 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19031 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore + (double)0.46364761;
19032 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.1180;
19033 if (dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19034 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19035 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore - (double)0.46364761;
19036 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.1180;
19037 if (dmisc28 == patrat3SHOTFAST || dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19038 if (dmisc28 == patrat5SHOT || dmisc28 == patrat5SHOTFAST)
19039 {
19040 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19041 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore + (double)0.78539816;
19042 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.4142;
19043 if (dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19044 addEwpn(x,y,z,wpn,3,wdp,dir,getUID(), 0, fakez);
19045 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->angle = anglestore - (double)0.78539816;
19046 ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step += 0.4142;
19047 if (dmisc28 == patrat5SHOTFAST) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->step *= 2;
19048 }
19049 }
19050 break;
19051
19052 }
19053 sfx(wpnsfx(wpn),pan(int32_t(x)));
19054 //+0.46364761
19055 //11.80
19056 }
19057
19058 void ePatra::draw(BITMAP *dest)
19059 {
19060 tile=o_tile;
19061 update_enemy_frame();
19062 enemy::draw(dest);
19063 }
19064
19065 int32_t ePatra::defend(int32_t wpnId, int32_t *power, int32_t edef)
19066 {
19067 int32_t ret = enemy::defend(wpnId, power, edef);
19068
19069 if(ret < 0 && (flycnt||flycnt2))
19070 return 0;
19071
19072 return ret;
19073 }
19074
19075 int32_t ePatra::defendNew(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable)
19076 {
19077 int32_t ret = enemy::defendNew(wpnId, power, edef, unblockable);
19078
19079 if(ret < 0 && (flycnt||flycnt2))
19080 return 0;
19081
19082 return ret;
19083 }
19084
19085 esPatra::esPatra(zfix X,zfix Y,int32_t Id,int32_t Clk, sprite * prnt) : enemy(X,Y,Id,Clk), parent(prnt)
19086 {
19087 //cs=8;
19088 item_set=0;
19089 misc=clk;
19090 clk4 = 0;
19091 clk5 = 0;
19092 clk = -((misc*21)>>1)-1;
19093 yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
19094 hxsz=12;
19095 hysz=12;
19096 hxofs=2;
19097 hyofs=2;
19098 extend = 0;
19099 txsz = 1;
19100 tysz = 1;
19101 /* //These need to be separate enemy editor fields. This enemy class also it's draw altered to correctly support big stuff.
19102 enemy *prntenemy = (enemy *) guys.getByUID(parent->getUID());
19103 int32_t prntSIZEflags = prntenemy->SIZEflags;
19104 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = prntenemy->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
19105 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
19106 // al_trace("Enemy txsz:%i\n", txsz);
19107 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = prntenemy->tysz; if ( tysz > 1 ) extend = 3; }
19108 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = prntenemy->hxsz;
19109 else
19110 hxsz=12;
19111 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = prntenemy->hysz;
19112 else
19113 hysz=12;
19114 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = prntenemy->hzsz;
19115 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = prntenemy->hxofs;
19116 else
19117 hxofs=2;
19118 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = prntenemy->hyofs;
19119 else hyofs=2;
19120 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
19121 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)prntenemy->xofs;
19122 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
19123 {
19124 yofs = (int32_t)prntenemy->yofs; //This seems to be setting to +48 or something with any value set?! -Z
19125 }
19126
19127 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)prntenemy->zofs;
19128 */
19129 mainguy=count_enemy=false;
19130 bgsfx=-1;
19131 //o_tile=0;
19132 flags &= (~guy_neverret);
19133 deadsfx = WAV_EDEAD;
19134 hitsfx = WAV_EHIT;
19135 isCore = false;
19136 }
19137
19138 bool esPatra::animate(int32_t index)
19139 {
19140 if(switch_hooked) return enemy::animate(index);
19141 if(dying)
19142 return Dead(index);
19143
19144 return enemy::animate(index);
19145 }
19146
19147 void esPatra::draw(BITMAP *dest)
19148 {
19149 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19150 {
19151 tile = o_tile+(clk&3);
19152
19153 switch(dir) //directions get screwed up after 8. *shrug*
19154 {
19155 case up: //u
19156 flip=0;
19157 break;
19158
19159 case down: //d
19160 flip=0;
19161 tile+=4;
19162 break;
19163
19164 case left: //l
19165 flip=0;
19166 tile+=8;
19167 break;
19168
19169 case right: //r
19170 flip=0;
19171 tile+=12;
19172 break;
19173
19174 case l_up: //ul
19175 flip=0;
19176 tile+=20;
19177 break;
19178
19179 case r_up: //ur
19180 flip=0;
19181 tile+=24;
19182 break;
19183
19184 case l_down: //dl
19185 flip=0;
19186 tile+=28;
19187 break;
19188
19189 case r_down: //dr
19190 flip=0;
19191 tile+=32;
19192 break;
19193 }
19194 }
19195 else
19196 {
19197 tile = o_tile+((clk&2)>>1);
19198 }
19199
19200 if(clk>=0)
19201 enemy::draw(dest);
19202 }
19203
19204
19205 ePatraBS::ePatraBS(zfix ,zfix ,int32_t Id,int32_t Clk) : enemy((zfix)128,(zfix)48,Id,Clk)
19206 {
19207 adjusted=false;
19208 dir=(zc_oldrand()&7)+8;
19209 step=0.25;
19210 clk4 = 0;
19211 clk5 = 0;
19212 //flycnt=6; flycnt2=0;
19213 flycnt=dmisc1;
19214 flycnt2=0; // PatraBS doesn't have inner rings!
19215 loopcnt=0;
19216
19217 SIZEflags = d->SIZEflags;
19218 if ( ((SIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = d->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
19219 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
19220 // al_trace("Enemy txsz:%i\n", txsz);
19221 if ( ((SIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = d->tysz; if ( tysz > 1 ) extend = 3; }
19222 if ( ((SIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = d->hxsz;
19223 else hxsz = 32;
19224 if ( ((SIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = d->hysz;
19225 if ( ((SIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = d->hzsz;
19226 if ( (SIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = d->hxofs;
19227 else hxofs=-8;
19228 if ( (SIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = d->hyofs;
19229 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
19230 if ( (SIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)d->xofs;
19231 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
19232 {
19233 yofs = (int32_t)d->yofs; //This seems to be setting to +48 or something with any value set?! -Z
19234 yofs += (get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset) ; //this offset fixes yofs not plaing properly. -Z
19235 }
19236
19237 if ( (SIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) zofs = (int32_t)d->zofs;
19238
19239 if(dmisc6<int16_t(1))dmisc6=1; // ratio cannot be 0!
19240
19241 //nets+4480;
19242 }
19243
19244 bool ePatraBS::animate(int32_t index)
19245 {
19246 if(switch_hooked) return enemy::animate(index);
19247 if(dying)
19248 return Dead(index);
19249
19250 if(clk==0)
19251 {
19252 removearmos(x,y,ffcactivated);
19253 }
19254
19255 variable_walk_8(rate,homing,hrate,spw_floater);
19256
19257 if(++clk2>90)
19258 {
19259 clk2=0;
19260
19261 if(loopcnt)
19262 --loopcnt;
19263 else
19264 {
19265 if((misc%dmisc6)==0)
19266 loopcnt=dmisc7;
19267 }
19268
19269 ++misc;
19270 }
19271
19272 // double size=1;;
19273 for(int32_t i=index+1; i<index+flycnt+1; i++)
19274 {
19275 if(!adjusted)
19276 {
19277 ((enemy*)guys.spr(i))->hp=dmisc3;
19278
19279 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19280 {
19281 ((enemy*)guys.spr(i))->o_tile=o_tile+dmisc8;
19282 }
19283 else
19284 {
19285 ((enemy*)guys.spr(i))->o_tile=o_tile+1;
19286 }
19287
19288 ((enemy*)guys.spr(i))->cs = dmisc9;
19289 }
19290
19291 if(((enemy*)guys.spr(i))->hp <= 0)
19292 {
19293 for(int32_t j=i; j<index+flycnt+flycnt2; j++)
19294 {
19295 guys.swap(j,j+1);
19296 }
19297
19298 --flycnt;
19299 }
19300 else
19301 {
19302 int32_t pos2 = ((enemy*)guys.spr(i))->misc;
19303 double a2 = ((int64_t)clk2-pos2*90/(dmisc1==0?1:dmisc1))*PI/45;
19304 temp_x = zc::math::Cos(a2+PI/2)*45;
19305 temp_y = -zc::math::Sin(a2+PI/2)*45;
19306
19307 if(loopcnt>0)
19308 {
19309 guys.spr(i)->x = zc::math::Cos(a2+PI/2)*45;
19310 guys.spr(i)->y = (-zc::math::Sin(a2+PI/2)-zc::math::Cos(pos2*PI*2/(dmisc1==0?1:dmisc1)))*22.5;
19311 }
19312 else
19313 {
19314 guys.spr(i)->x = temp_x;
19315 guys.spr(i)->y = temp_y;
19316 }
19317
19318 double _MSVC2022_tmp1, _MSVC2022_tmp2;
19319 double ddir=atan2_MSVC2022_FIX(double(temp_y),double(temp_x));
19320
19321 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
19322 {
19323 guys.spr(i)->dir=l_down;
19324 }
19325 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
19326 {
19327 guys.spr(i)->dir=left;
19328 }
19329 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
19330 {
19331 guys.spr(i)->dir=l_up;
19332 }
19333 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
19334 {
19335 guys.spr(i)->dir=up;
19336 }
19337 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
19338 {
19339 guys.spr(i)->dir=r_up;
19340 }
19341 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
19342 {
19343 guys.spr(i)->dir=right;
19344 }
19345 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
19346 {
19347 guys.spr(i)->dir=r_down;
19348 }
19349 else
19350 {
19351 guys.spr(i)->dir=down;
19352 }
19353
19354 guys.spr(i)->x += x;
19355 guys.spr(i)->y += y;
19356 }
19357 }
19358
19359 adjusted=true;
19360 return enemy::animate(index);
19361 }
19362
19363 void ePatraBS::draw(BITMAP *dest)
19364 {
19365 tile=o_tile;
19366
19367 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19368 {
19369 double _MSVC2022_tmp1, _MSVC2022_tmp2;
19370 double ddir=atan2_MSVC2022_FIX(double(y-(Hero.y)),double(Hero.x-x));
19371
19372 if((ddir<=(((-5)*PI)/8))&&(ddir>(((-7)*PI)/8)))
19373 {
19374 lookat=l_down;
19375 }
19376 else if((ddir<=(((-3)*PI)/8))&&(ddir>(((-5)*PI)/8)))
19377 {
19378 lookat=down;
19379 }
19380 else if((ddir<=(((-1)*PI)/8))&&(ddir>(((-3)*PI)/8)))
19381 {
19382 lookat=r_down;
19383 }
19384 else if((ddir<=(((1)*PI)/8))&&(ddir>(((-1)*PI)/8)))
19385 {
19386 lookat=right;
19387 }
19388 else if((ddir<=(((3)*PI)/8))&&(ddir>(((1)*PI)/8)))
19389 {
19390 lookat=r_up;
19391 }
19392 else if((ddir<=(((5)*PI)/8))&&(ddir>(((3)*PI)/8)))
19393 {
19394 lookat=up;
19395 }
19396 else if((ddir<=(((7)*PI)/8))&&(ddir>(((5)*PI)/8)))
19397 {
19398 lookat=l_up;
19399 }
19400 else
19401 {
19402 lookat=left;
19403 }
19404
19405 switch(lookat) //directions get screwed up after 8. *shrug*
19406 {
19407 case up: //u
19408 flip=0;
19409 break;
19410
19411 case down: //d
19412 flip=0;
19413 tile+=8;
19414 break;
19415
19416 case left: //l
19417 flip=0;
19418 tile+=40;
19419 break;
19420
19421 case right: //r
19422 flip=0;
19423 tile+=48;
19424 break;
19425
19426 case l_up: //ul
19427 flip=0;
19428 tile+=80;
19429 break;
19430
19431 case r_up: //ur
19432 flip=0;
19433 tile+=88;
19434 break;
19435
19436 case l_down: //dl
19437 flip=0;
19438 tile+=120;
19439 break;
19440
19441 case r_down: //dr
19442 flip=0;
19443 tile+=128;
19444 break;
19445 }
19446
19447 tile+=(2*(clk&3));
19448 xofs-=8;
19449 yofs-=8;
19450 drawblock(dest,15);
19451 xofs+=8;
19452 yofs+=8;
19453 }
19454 else
19455 {
19456 flip=(clk&1);
19457 xofs-=8;
19458 yofs-=8;
19459 enemy::draw(dest);
19460 xofs+=16;
19461 enemy::draw(dest);
19462 yofs+=16;
19463 enemy::draw(dest);
19464 xofs-=16;
19465 enemy::draw(dest);
19466 xofs+=8;
19467 yofs-=8;
19468 }
19469 }
19470
19471 int32_t ePatraBS::defend(int32_t wpnId, int32_t *power, int32_t edef)
19472 {
19473 int32_t ret = enemy::defend(wpnId, power, edef);
19474
19475 if(ret < 0 && (flycnt||flycnt2))
19476 return 0;
19477
19478 return ret;
19479 }
19480
19481 int32_t ePatraBS::defendNew(int32_t wpnId, int32_t *power, int32_t edef, byte unblockable)
19482 {
19483 int32_t ret = enemy::defendNew(wpnId, power, edef, unblockable);
19484
19485 if(ret < 0 && (flycnt||flycnt2))
19486 return 0;
19487
19488 return ret;
19489 }
19490
19491 esPatraBS::esPatraBS(zfix X,zfix Y,int32_t Id,int32_t Clk, sprite * prnt) : enemy(X,Y,Id,Clk), parent(prnt)
19492 {
19493 //cs=csBOSS;
19494 item_set=0;
19495 misc=clk;
19496 clk = -((misc*21)>>1)-1;
19497 clk4 = 0;
19498 clk5 = 0;
19499 enemy *prntenemy = (enemy *) guys.getByUID(parent->getUID());
19500 int32_t prntSIZEflags = prntenemy->SIZEflags;
19501 if ( ((prntSIZEflags&guyflagOVERRIDE_TILE_WIDTH) != 0) && txsz > 0 ) { txsz = prntenemy->txsz; if ( txsz > 1 ) extend = 3; } //! Don;t forget to set extend if the tilesize is > 1.
19502 //al_trace("->txsz:%i\n", txsz); Verified that this is setting the value. -Z
19503 // al_trace("Enemy txsz:%i\n", txsz);
19504 if ( ((prntSIZEflags&guyflagOVERRIDE_TILE_HEIGHT) != 0) && tysz > 0 ) { tysz = prntenemy->tysz; if ( tysz > 1 ) extend = 3; }
19505 if ( ((prntSIZEflags&guyflagOVERRIDE_HIT_WIDTH) != 0) && hxsz >= 0 ) hxsz = prntenemy->hxsz;
19506 else hxsz=16;
19507 if ( ((prntSIZEflags&guyflagOVERRIDE_HIT_HEIGHT) != 0) && hysz >= 0 ) hysz = prntenemy->hysz;
19508 else hysz=16;
19509 if ( ((prntSIZEflags&guyflagOVERRIDE_HIT_Z_HEIGHT) != 0) && hzsz >= 0 ) hzsz = prntenemy->hzsz;
19510 if ( (prntSIZEflags&guyflagOVERRIDE_HIT_X_OFFSET) != 0 ) hxofs = prntenemy->hxofs;
19511 if ( (prntSIZEflags&guyflagOVERRIDE_HIT_Y_OFFSET) != 0 ) hyofs = prntenemy->hyofs;
19512 else hyofs=2;
19513 // if ( (SIZEflags&guyflagOVERRIDEHITZOFFSET) != 0 ) hzofs = hzofs;
19514 if ( (prntSIZEflags&guyflagOVERRIDE_DRAW_X_OFFSET) != 0 ) xofs = (int32_t)prntenemy->xofs;
19515 if ( (prntSIZEflags&guyflagOVERRIDE_DRAW_Y_OFFSET) != 0 )
19516 {
19517 yofs = (int32_t)prntenemy->yofs;
19518 }
19519 else yofs=(get_bit(quest_rules, qr_OLD_DRAWOFFSET)?playing_field_offset:original_playing_field_offset);
19520 if ( (prntSIZEflags&guyflagOVERRIDE_DRAW_Z_OFFSET) != 0 ) prntenemy->zofs = (int32_t)zofs;
19521
19522 bgsfx=-1;
19523 mainguy=count_enemy=false;
19524 deadsfx = WAV_EDEAD;
19525 hitsfx = WAV_EHIT;
19526 flags &= ~guy_neverret;
19527 isCore = false;
19528 }
19529
19530 bool esPatraBS::animate(int32_t index)
19531 {
19532 if(switch_hooked) return enemy::animate(index);
19533 if(dying)
19534 return Dead(index);
19535
19536 return enemy::animate(index);
19537 }
19538
19539 void esPatraBS::draw(BITMAP *dest)
19540 {
19541 tile=o_tile;
19542
19543 if(get_bit(quest_rules,qr_NEWENEMYTILES))
19544 {
19545 switch(dir) //directions get screwed up after 8. *shrug*
19546 {
19547 case up: //u
19548 flip=0;
19549 break;
19550
19551 case down: //d
19552 flip=0;
19553 tile+=4;
19554 break;
19555
19556 case left: //l
19557 flip=0;
19558 tile+=8;
19559 break;
19560
19561 case right: //r
19562 flip=0;
19563 tile+=12;
19564 break;
19565
19566 case l_up: //ul
19567 flip=0;
19568 tile+=20;
19569 break;
19570
19571 case r_up: //ur
19572 flip=0;
19573 tile+=24;
19574 break;
19575
19576 case l_down: //dl
19577 flip=0;
19578 tile+=28;
19579 break;
19580
19581 case r_down: //dr
19582 flip=0;
19583 tile+=32;
19584 break;
19585 }
19586
19587 tile += ((clk&6)>>1);
19588 }
19589 else
19590 {
19591 tile += (clk&4)?1:0;
19592 }
19593
19594 if(clk>=0)
19595 enemy::draw(dest);
19596 }
19597
19598
19599 /**********************************/
19600 /********** Misc Code ***********/
19601 /**********************************/
19602
19603 47 void addEwpn(int32_t x,int32_t y,int32_t z,int32_t id,int32_t type,int32_t power,int32_t dir, int32_t parentid, byte script_generated, int32_t fakez)
19604 {
19605
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
47 if(id>wEnemyWeapons || (id >= wScript1 && id <= wScript10))
19606
4/8
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 47 times.
✗ Branch 7 not taken.
47 Ewpns.add(new weapon((zfix)x,(zfix)y,(zfix)z,id,type,power,dir, -1, parentid, script_generated));
19607
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 if (fakez > 0) ((weapon*)(Ewpns.spr(Ewpns.Count()-1)))->fakez = fakez;
19608 47 }
19609
19610 175 int32_t hit_enemy(int32_t index, int32_t wpnId,int32_t power,int32_t wpnx,int32_t wpny,int32_t dir, int32_t enemyHitWeapon)
19611 {
19612 // Kludge
19613
4/8
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 175 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 175 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 175 times.
✗ Branch 7 not taken.
175 weapon *w = new weapon((zfix)wpnx,(zfix)wpny,(zfix)0,wpnId,0,power,dir,enemyHitWeapon,-1,false);
19614 175 int32_t ret= ((enemy*)guys.spr(index))->takehit(w);
19615
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 175 times.
175 delete w;
19616 175 return ret;
19617 }
19618
19619 20 void enemy_scored(int32_t index)
19620 {
19621 20 ((enemy*)guys.spr(index))->scored=true;
19622 20 }
19623
19624 29 void addguy(int32_t x,int32_t y,int32_t id,int32_t clk,bool mainguy)
19625 {
19626
7/12
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 29 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 24 times.
✓ Branch 10 taken 29 times.
✗ Branch 11 not taken.
29 guy *g = new guy((zfix)x,(zfix)(y+(isdungeon()?1:0)),id,get_bit(quest_rules,qr_NOGUYPOOF)?0:clk,mainguy);
19627 29 guys.add(g);
19628 29 }
19629
19630 22 void additem(int32_t x,int32_t y,int32_t id,int32_t pickup)
19631 {
19632
5/10
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 22 times.
✗ Branch 9 not taken.
22 item *i = new item(zfix(x), zfix(y - get_bit(quest_rules, qr_NOITEMOFFSET)), zfix(0), id, pickup, 0);
19633 22 items.add(i);
19634 22 }
19635
19636 void additem(int32_t x,int32_t y,int32_t id,int32_t pickup,int32_t clk)
19637 {
19638 item *i = new item((zfix)x,(zfix)y-(get_bit(quest_rules, qr_NOITEMOFFSET)),(zfix)0,id,pickup,clk);
19639 items.add(i);
19640 }
19641
19642 void adddummyitem(int32_t x,int32_t y,int32_t id,int32_t pickup)
19643 {
19644 item *i = new item((zfix)x,(zfix)y-(get_bit(quest_rules, qr_NOITEMOFFSET)),(zfix)0,id,pickup,0,true);
19645 items.add(i);
19646 }
19647
19648 void kill_em_all()
19649 {
19650 for(int32_t i=0; i<guys.Count(); i++)
19651 {
19652 enemy *e = ((enemy*)guys.spr(i));
19653
19654 if(e->flags&(1<<3) && !(e->family == eeGHINI && e->dmisc1 == 1)) continue;
19655
19656 e->kickbucket();
19657 }
19658 }
19659
19660 bool can_kill_em_all()
19661 {
19662 for(int32_t i=0; i<guys.Count(); i++)
19663 {
19664 enemy *e = ((enemy*)guys.spr(i));
19665
19666 if(e->flags&(1<<3) && !(e->family == eeGHINI && e->dmisc1 == 1)) continue;
19667 if(e->superman) continue;
19668 return true;
19669 }
19670 return false;
19671 }
19672
19673 //This needs a quest rule, or enemy flag, Dying Enemy Doesn't Hurt Hero
19674 // For Hero's hit detection. Don't count them if they are stunned or are guys.
19675 int32_t GuyHit(int32_t tx,int32_t ty,int32_t tz,int32_t txsz,int32_t tysz,int32_t tzsz)
19676 {
19677 for(int32_t i=0; i<guys.Count(); i++)
19678 {
19679 if(guys.spr(i)->hit(tx,ty,tz,txsz,tysz,tzsz))
19680 {
19681 if(((enemy*)guys.spr(i))->stunclk==0 && ((enemy*)guys.spr(i))->frozenclock==0 && (!get_bit(quest_rules, qr_SAFEENEMYFADE) || ((enemy*)guys.spr(i))->fading != fade_flicker)
19682 &&(((enemy*)guys.spr(i))->d->family != eeGUY || ((enemy*)guys.spr(i))->dmisc1))
19683 {
19684 return i;
19685 }
19686 }
19687 }
19688
19689 return -1;
19690 }
19691
19692 76297 int32_t GuyHitFrom(int32_t index,int32_t tx,int32_t ty,int32_t tz,int32_t txsz,int32_t tysz,int32_t tzsz)
19693 {
19694
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 76297 times.
✓ Branch 2 taken 177732 times.
✓ Branch 3 taken 75254 times.
252986 for(int32_t i=zc_max(0, index); i<guys.Count(); i++)
19695 {
19696
2/2
✓ Branch 0 taken 1043 times.
✓ Branch 1 taken 176689 times.
177732 if(guys.spr(i)->hit(tx,ty,tz,txsz,tysz,tzsz))
19697 {
19698 1043 return i;
19699 }
19700 176689 }
19701
19702 75254 return -1;
19703 76297 }
19704
19705 // For Hero's hit detection. Count them if they are dying.
19706 171 int32_t GuyHit(int32_t index,int32_t tx,int32_t ty,int32_t tz,int32_t txsz,int32_t tysz,int32_t tzsz)
19707 {
19708 171 enemy *e = (enemy*)guys.spr(index);
19709
3/4
✓ Branch 0 taken 171 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 104 times.
171 if(!e || e->hp > 0)
19710 67 return -1;
19711
19712 104 bool d = e->dying;
19713 104 int32_t hc = e->hclk;
19714 104 e->dying = false;
19715 104 e->hclk = 0;
19716 104 bool hit = e->hit(tx,ty,tz,txsz,tysz,tzsz);
19717 104 e->dying = d;
19718 104 e->hclk = hc;
19719
19720
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 102 times.
104 return hit ? index : -1;
19721 171 }
19722
19723 80334 bool hasMainGuy()
19724 {
19725
2/2
✓ Branch 0 taken 66243 times.
✓ Branch 1 taken 33471 times.
99714 for(int32_t i=0; i<guys.Count(); i++)
19726 {
19727
2/2
✓ Branch 0 taken 46863 times.
✓ Branch 1 taken 19380 times.
66243 if(((enemy*)guys.spr(i))->mainguy)
19728 {
19729 46863 return true;
19730 }
19731 19380 }
19732
19733 33471 return false;
19734 80334 }
19735
19736 void EatHero(int32_t index)
19737 {
19738 ((eStalfos*)guys.spr(index))->eathero();
19739 }
19740
19741 void GrabHero(int32_t index)
19742 {
19743 ((eWallM*)guys.spr(index))->grabhero();
19744 }
19745
19746 bool CarryHero()
19747 {
19748 for(int32_t i=0; i<guys.Count(); i++)
19749 {
19750 if(((guy*)(guys.spr(i)))->family==eeWALLM)
19751 {
19752 if(((eWallM*)guys.spr(i))->hashero)
19753 {
19754 Hero.x=guys.spr(i)->x;
19755 Hero.y=guys.spr(i)->y;
19756 return ((eWallM*)guys.spr(i))->misc > 0;
19757 }
19758 }
19759
19760 // Like Likes currently can't carry Hero.
19761 /*
19762 if(((guy*)(guys.spr(i)))->family==eeLIKE)
19763 {
19764 if(((eLikeLike*)guys.spr(i))->hashero)
19765 {
19766 Hero.x=guys.spr(i)->x;
19767 Hero.y=guys.spr(i)->y;
19768 return (true);
19769 }
19770 }*/
19771 }
19772
19773 return false;
19774 }
19775
19776 // Move item with guy
19777 void movefairy(zfix &x,zfix &y,int32_t misc)
19778 {
19779 int32_t i = guys.idFirst(eITEMFAIRY+0x1000*misc);
19780
19781 if(i!=-1)
19782 {
19783 x = guys.spr(i)->x;
19784 y = guys.spr(i)->y;
19785 }
19786 }
19787
19788 // Move guy with item (used by FFC scripts and hookshot-dragged fairies)
19789 void movefairy2(zfix x,zfix y,int32_t misc)
19790 {
19791 int32_t i = guys.idFirst(eITEMFAIRY+0x1000*misc);
19792
19793 if(i!=-1)
19794 {
19795 guys.spr(i)->x = x;
19796 guys.spr(i)->y = y;
19797 }
19798 }// Move item with guy
19799
19800 362 void movefairynew(zfix &x,zfix &y, item const &itemfairy)
19801 {
19802 362 enemy *fairy = (enemy *) guys.getByUID(itemfairy.fairyUID);
19803
19804
1/2
✓ Branch 0 taken 362 times.
✗ Branch 1 not taken.
362 if(fairy)
19805 {
19806 362 x = fairy->x;
19807 362 y = fairy->y;
19808 362 }
19809 362 }
19810
19811 // Move guy with item (used by FFC scripts and hookshot-dragged fairies)
19812 void movefairynew2(zfix x,zfix y, item const &itemfairy)
19813 {
19814 enemy *fairy = (enemy *) guys.getByUID(itemfairy.fairyUID);
19815
19816 if(fairy)
19817 {
19818 fairy->x = x;
19819 fairy->y = y;
19820 }
19821 }
19822
19823 void killfairy(int32_t misc)
19824 {
19825 int32_t i = guys.idFirst(eITEMFAIRY+0x1000*misc);
19826 guys.del(i);
19827 }
19828
19829 int32_t getGuyIndex(const int32_t eid)
19830 {
19831 for(word i = 0; i < guys.Count(); i++)
19832 {
19833 if(guys.spr(i)->getUID() == eid)
19834 return i;
19835 }
19836
19837 return -1;
19838 }
19839
19840 void killfairynew(item const &itemfairy)
19841 {
19842 enemy *fairy = (enemy *) guys.getByUID(itemfairy.fairyUID);
19843 if (fairy != NULL) guys.del(getGuyIndex(itemfairy.fairyUID));
19844 }
19845
19846 //Should probably change this to return an 'enemy*', null on failure -Em
19847 54 int32_t addenemy(int32_t x,int32_t y,int32_t id,int32_t clk)
19848 {
19849 54 return addenemy(x,y,0,id,clk);
19850 }
19851
19852 int32_t addchild(int32_t x,int32_t y,int32_t id,int32_t clk, int32_t parent_scriptUID)
19853 {
19854 return addchild(x,y,0,id,clk, parent_scriptUID);
19855 }
19856
19857 int32_t addchild(int32_t x,int32_t y,int32_t z,int32_t id,int32_t clk, int32_t parent_scriptUID)
19858 {
19859 if(id <= 0) return 0;
19860
19861 int32_t ret = 0;
19862 sprite *e=NULL;
19863 al_trace("Adding child\n");
19864
19865 switch(guysbuf[id&0xFFF].family)
19866 {
19867 //Fixme: possible enemy memory leak. (minor)
19868 case eeWALK:
19869 e = new eStalfos((zfix)x,(zfix)y,id,clk);
19870 break;
19871
19872 case eeLEV:
19873 e = new eLeever((zfix)x,(zfix)y,id,clk);
19874 break;
19875
19876 case eeTEK:
19877 e = new eTektite((zfix)x,(zfix)y,id,clk);
19878 break;
19879
19880 case eePEAHAT:
19881 e = new ePeahat((zfix)x,(zfix)y,id,clk);
19882 break;
19883
19884 case eeZORA:
19885 e = new eZora((zfix)x,(zfix)y,id,clk);
19886 break;
19887
19888 case eeGHINI:
19889 e = new eGhini((zfix)x,(zfix)y,id,clk);
19890 break;
19891
19892 case eeKEESE:
19893 e = new eKeese((zfix)x,(zfix)y,id,clk);
19894 break;
19895
19896 case eeWIZZ:
19897 e = new eWizzrobe((zfix)x,(zfix)y,id,clk);
19898 break;
19899
19900 case eePROJECTILE:
19901 e = new eProjectile((zfix)x,(zfix)y,id,clk);
19902 break;
19903
19904 case eeWALLM:
19905 e = new eWallM((zfix)x,(zfix)y,id,clk);
19906 break;
19907
19908 case eeAQUA:
19909 e = new eAquamentus((zfix)x,(zfix)y,id,clk);
19910 break;
19911
19912 case eeMOLD:
19913 e = new eMoldorm((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
19914 break;
19915
19916 case eeMANHAN:
19917 e = new eManhandla((zfix)x,(zfix)y,id,clk);
19918 break;
19919
19920 case eeGLEEOK:
19921 e = new eGleeok((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
19922 break;
19923
19924 case eeGHOMA:
19925 e = new eGohma((zfix)x,(zfix)y,id,clk);
19926 break;
19927
19928 case eeLANM:
19929 e = new eLanmola((zfix)x,(zfix)y,id,zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)));
19930 break;
19931
19932 case eeGANON:
19933 e = new eGanon((zfix)x,(zfix)y,id,clk);
19934 break;
19935
19936 case eeFAIRY:
19937 e = new eItemFairy((zfix)x,(zfix)y,id+0x1000*clk,clk);
19938 break;
19939
19940 case eeFIRE:
19941 e = new eFire((zfix)x,(zfix)y,id,clk);
19942 break;
19943
19944 case eeOTHER:
19945 e = new eOther((zfix)x,(zfix)y,id,clk);
19946 break;
19947
19948
19949 case eeSCRIPT01:
19950 case eeSCRIPT02:
19951 case eeSCRIPT03:
19952 case eeSCRIPT04:
19953 case eeSCRIPT05:
19954 case eeSCRIPT06:
19955 case eeSCRIPT07:
19956 case eeSCRIPT08:
19957 case eeSCRIPT09:
19958 case eeSCRIPT10:
19959 case eeSCRIPT11:
19960 case eeSCRIPT12:
19961 case eeSCRIPT13:
19962 case eeSCRIPT14:
19963 case eeSCRIPT15:
19964 case eeSCRIPT16:
19965 case eeSCRIPT17:
19966 case eeSCRIPT18:
19967 case eeSCRIPT19:
19968 case eeSCRIPT20:
19969 {
19970 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
19971 {
19972 e = new eScript((zfix)x,(zfix)y,id,clk);
19973 break;
19974 }
19975 else return 0;
19976 }
19977
19978 case eeFFRIENDLY01:
19979 case eeFFRIENDLY02:
19980 case eeFFRIENDLY03:
19981 case eeFFRIENDLY04:
19982 case eeFFRIENDLY05:
19983 case eeFFRIENDLY06:
19984 case eeFFRIENDLY07:
19985 case eeFFRIENDLY08:
19986 case eeFFRIENDLY09:
19987 case eeFFRIENDLY10:
19988 {
19989 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
19990 {
19991 e = new eFriendly((zfix)x,(zfix)y,id,clk); break;
19992 }
19993 else return 0;
19994
19995 }
19996
19997 case eeSPINTILE:
19998 e = new eSpinTile((zfix)x,(zfix)y,id,clk);
19999 break;
20000
20001 // and these enemies use the misc10/misc2 value
20002 case eeROCK:
20003 {
20004 switch(guysbuf[id&0xFFF].misc10)
20005 {
20006 case 1:
20007 e = new eBoulder((zfix)x,(zfix)y,id,clk);
20008 break;
20009
20010 case 0:
20011 default:
20012 e = new eRock((zfix)x,(zfix)y,id,clk);
20013 break;
20014 }
20015
20016 break;
20017 }
20018
20019 case eeTRAP:
20020 {
20021 switch(guysbuf[id&0xFFF].misc2)
20022 {
20023 case 1:
20024 e = new eTrap2((zfix)x,(zfix)y,id,clk);
20025 break;
20026
20027 case 0:
20028 default:
20029 e = new eTrap((zfix)x,(zfix)y,id,clk);
20030 break;
20031 }
20032
20033 break;
20034 }
20035
20036 case eeDONGO:
20037 {
20038 switch(guysbuf[id&0xFFF].misc10)
20039 {
20040 case 1:
20041 e = new eDodongo2((zfix)x,(zfix)y,id,clk);
20042 break;
20043
20044 case 0:
20045 default:
20046 e = new eDodongo((zfix)x,(zfix)y,id,clk);
20047 break;
20048 }
20049
20050 break;
20051 }
20052
20053 case eeDIG:
20054 {
20055 switch(guysbuf[id&0xFFF].misc10)
20056 {
20057 case 1:
20058 e = new eLilDig((zfix)x,(zfix)y,id,clk);
20059 break;
20060
20061 case 0:
20062 default:
20063 e = new eBigDig((zfix)x,(zfix)y,id,clk);
20064 break;
20065 }
20066
20067 break;
20068 }
20069
20070 case eePATRA:
20071 {
20072 switch(guysbuf[id&0xFFF].misc10)
20073 {
20074 case 1:
20075 if (get_bit(quest_rules,qr_HARDCODED_BS_PATRA))
20076 {
20077 e = new ePatraBS((zfix)x,(zfix)y,id,clk);
20078 break;
20079 }
20080 [[fallthrough]];
20081 case 0:
20082 default:
20083 e = new ePatra((zfix)x,(zfix)y,id,clk);
20084 break;
20085 }
20086
20087 break;
20088 }
20089
20090 case eeGUY:
20091 {
20092 switch(guysbuf[id&0xFFF].misc10)
20093 {
20094 case 1:
20095 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20096 break;
20097
20098 case 0:
20099 default:
20100 e = new eNPC((zfix)x,(zfix)y,id,clk);
20101 break;
20102 }
20103
20104 break;
20105 }
20106
20107 case eeNONE:
20108 if(guysbuf[id&0xFFF].misc10 ==1)
20109 {
20110 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20111 break;
20112 break;
20113 }
20114 [[fallthrough]];
20115 default:
20116
20117 return 0;
20118 }
20119
20120 ret++; // Made one enemy.
20121
20122 if(z && canfall(id))
20123 {
20124 e->z = (zfix)z;
20125 }
20126
20127 ((enemy*)e)->ceiling = (z && canfall(id));
20128 ((enemy*)e)->parent_script_UID = parent_scriptUID;
20129 //al_trace("Child Script UID: %d\n",((enemy*)e)->script_UID);
20130 //zprint2("Child Script UID: %d\n",((enemy*)e)->script_UID);
20131 //al_trace("Child's Parent UID: %d\n",((enemy*)e)->parent_script_UID);
20132 //zprint2("Child's Parent UID: %d\n",((enemy*)e)->parent_script_UID);
20133
20134
20135 if(!guys.add(e))
20136 {
20137 return 0;
20138 }
20139
20140 // add segments of segmented enemies
20141 int32_t c=0;
20142
20143 switch(guysbuf[id&0xFFF].family)
20144 {
20145 case eeMOLD:
20146 {
20147 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20148 id &= 0xFFF;
20149
20150 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id].misc1)); i++)
20151 {
20152 //christ this is messy -DD
20153 int32_t segclk = -i*((int32_t)(8.0/(zslongToFix(guysbuf[id&0xFFF].step*100))));
20154
20155 if(!guys.add(new esMoldorm((zfix)x,(zfix)y,id+0x1000,segclk)))
20156 {
20157 al_trace("Moldorm segment %d could not be created!\n",i+1);
20158
20159 for(int32_t j=0; j<i+1; j++)
20160 guys.del(guys.Count()-1);
20161
20162 return 0;
20163 }
20164
20165 if(i>0)
20166 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20167
20168 ret++;
20169 }
20170
20171 break;
20172 }
20173
20174 case eeLANM:
20175 {
20176 id &= 0xFFF;
20177 int32_t shft = guysbuf[id].misc2;
20178 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20179
20180 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x1000,0)))
20181 {
20182 al_trace("Lanmola segment 1 could not be created!\n");
20183 guys.del(guys.Count()-1);
20184 return 0;
20185 }
20186
20187 ret++;
20188
20189 for(int32_t i=1; i<zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)); i++)
20190 {
20191 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x2000,-(i<<shft))))
20192 {
20193 al_trace("Lanmola segment %d could not be created!\n",i+1);
20194
20195 for(int32_t j=0; j<i+1; j++)
20196 guys.del(guys.Count()-1);
20197
20198 return 0;
20199 }
20200
20201 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20202 ret++;
20203 }
20204 }
20205 break;
20206
20207 case eeMANHAN:
20208 id &= 0xFFF;
20209
20210 for(int32_t i=0; i<((!(guysbuf[id].misc2))?4:8); i++)
20211 {
20212 if(!guys.add(new esManhandla((zfix)x,(zfix)y,id+0x1000,i)))
20213 {
20214 al_trace("Manhandla head %d could not be created!\n",i+1);
20215
20216 for(int32_t j=0; j<i+1; j++)
20217 {
20218 guys.del(guys.Count()-1);
20219 }
20220
20221 return 0;
20222 }
20223
20224 ret++;
20225 ((enemy*)guys.spr(guys.Count()-1))->frate=guysbuf[id].misc1;
20226 }
20227
20228 break;
20229
20230 case eeGLEEOK:
20231 {
20232 id &= 0xFFF;
20233
20234 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)); i++)
20235 {
20236 if(!guys.add(new esGleeok((zfix)x,(zfix)y,id+0x1000,c, e)))
20237 {
20238 al_trace("Gleeok head %d could not be created!\n",i+1);
20239
20240 for(int32_t j=0; j<i+1; j++)
20241 {
20242 guys.del(guys.Count()-1);
20243 }
20244
20245 return false;
20246 }
20247
20248 c-=guysbuf[id].misc4;
20249 ret++;
20250 }
20251 }
20252 break;
20253
20254
20255 case eePATRA:
20256 {
20257 id &= 0xFFF;
20258 int32_t outeyes = 0;
20259
20260 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc1); i++)
20261 {
20262 if(!((guysbuf[id].misc10&&get_bit(quest_rules,qr_HARDCODED_BS_PATRA))?guys.add(new esPatraBS((zfix)x,(zfix)y,id+0x1000,i,e)):guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e))))
20263 {
20264 al_trace("Patra outer eye %d could not be created!\n",i+1);
20265
20266 for(int32_t j=0; j<i+1; j++)
20267 guys.del(guys.Count()-1);
20268
20269 return 0;
20270 }
20271 else
20272 outeyes++;
20273
20274 ret++;
20275 }
20276
20277 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc2); i++)
20278 {
20279 if(!guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e)))
20280 {
20281 al_trace("Patra inner eye %d could not be created!\n",i+1);
20282
20283 for(int32_t j=0; j<i+1+zc_min(254,outeyes); j++)
20284 guys.del(guys.Count()-1);
20285
20286 return 0;
20287 }
20288
20289 ret++;
20290 }
20291
20292 break;
20293 }
20294 }
20295
20296 return ret;
20297 }
20298
20299 // Returns number of enemies/segments created
20300 407 int32_t addenemy(int32_t x,int32_t y,int32_t z,int32_t id,int32_t clk)
20301 {
20302 //zprint2("addenemy id is: %d\n", (id&0xFFF));
20303 407 int32_t realid = id&0xFFF;
20304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 if( realid > MAXGUYS )
20305 {
20306 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "addenemy()");
20307 return 0;
20308 }
20309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 if(id <= 0) return 0;
20310
20311 407 int32_t ret = 0;
20312 407 sprite *e=NULL;
20313
20314
9/31
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 259 times.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 19 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 88 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 16 times.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 3 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
407 switch(guysbuf[id&0xFFF].family)
20315 {
20316 //Fixme: possible enemy memory leak. (minor)
20317 case eeWALK:
20318
3/6
✓ Branch 0 taken 259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 259 times.
✗ Branch 5 not taken.
259 e = new eStalfos((zfix)x,(zfix)y,id,clk);
20319 259 break;
20320
20321 case eeLEV:
20322
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 e = new eLeever((zfix)x,(zfix)y,id,clk);
20323 4 break;
20324
20325 case eeTEK:
20326
3/6
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
19 e = new eTektite((zfix)x,(zfix)y,id,clk);
20327 19 break;
20328
20329 case eePEAHAT:
20330 e = new ePeahat((zfix)x,(zfix)y,id,clk);
20331 break;
20332
20333 case eeZORA:
20334
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 e = new eZora((zfix)x,(zfix)y,id,clk);
20335 10 break;
20336
20337 case eeGHINI:
20338 e = new eGhini((zfix)x,(zfix)y,id,clk);
20339 break;
20340
20341 case eeKEESE:
20342
3/6
✓ Branch 0 taken 88 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
88 e = new eKeese((zfix)x,(zfix)y,id,clk);
20343 88 break;
20344
20345 case eeWIZZ:
20346 e = new eWizzrobe((zfix)x,(zfix)y,id,clk);
20347 break;
20348
20349 case eePROJECTILE:
20350
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 e = new eProjectile((zfix)x,(zfix)y,id,clk);
20351 6 break;
20352
20353 case eeWALLM:
20354
3/6
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 e = new eWallM((zfix)x,(zfix)y,id,clk);
20355 16 break;
20356
20357 case eeAQUA:
20358
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 e = new eAquamentus((zfix)x,(zfix)y,id,clk);
20359 2 break;
20360
20361 case eeMOLD:
20362 e = new eMoldorm((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
20363 break;
20364
20365 case eeMANHAN:
20366 e = new eManhandla((zfix)x,(zfix)y,id,clk);
20367 break;
20368
20369 case eeGLEEOK:
20370 e = new eGleeok((zfix)x,(zfix)y,id,zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)));
20371 break;
20372
20373 case eeGHOMA:
20374 e = new eGohma((zfix)x,(zfix)y,id,clk);
20375 break;
20376
20377 case eeLANM:
20378 e = new eLanmola((zfix)x,(zfix)y,id,zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)));
20379 break;
20380
20381 case eeGANON:
20382 e = new eGanon((zfix)x,(zfix)y,id,clk);
20383 break;
20384
20385 case eeFAIRY:
20386
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 e = new eItemFairy((zfix)x,(zfix)y,id+0x1000*clk,clk);
20387 3 break;
20388
20389 case eeFIRE:
20390 e = new eFire((zfix)x,(zfix)y,id,clk);
20391 break;
20392
20393 case eeOTHER:
20394 e = new eOther((zfix)x,(zfix)y,id,clk);
20395 break;
20396
20397
20398 case eeSCRIPT01:
20399 case eeSCRIPT02:
20400 case eeSCRIPT03:
20401 case eeSCRIPT04:
20402 case eeSCRIPT05:
20403 case eeSCRIPT06:
20404 case eeSCRIPT07:
20405 case eeSCRIPT08:
20406 case eeSCRIPT09:
20407 case eeSCRIPT10:
20408 case eeSCRIPT11:
20409 case eeSCRIPT12:
20410 case eeSCRIPT13:
20411 case eeSCRIPT14:
20412 case eeSCRIPT15:
20413 case eeSCRIPT16:
20414 case eeSCRIPT17:
20415 case eeSCRIPT18:
20416 case eeSCRIPT19:
20417 case eeSCRIPT20:
20418 {
20419 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
20420 {
20421 e = new eScript((zfix)x,(zfix)y,id,clk);
20422 break;
20423 }
20424 else return 0;
20425 }
20426
20427 case eeFFRIENDLY01:
20428 case eeFFRIENDLY02:
20429 case eeFFRIENDLY03:
20430 case eeFFRIENDLY04:
20431 case eeFFRIENDLY05:
20432 case eeFFRIENDLY06:
20433 case eeFFRIENDLY07:
20434 case eeFFRIENDLY08:
20435 case eeFFRIENDLY09:
20436 case eeFFRIENDLY10:
20437 {
20438 if ( !get_bit(quest_rules, qr_SCRIPT_FRIENDLY_ENEMY_TYPES) )
20439 {
20440 e = new eFriendly((zfix)x,(zfix)y,id,clk); break;
20441 }
20442 else return 0;
20443
20444 }
20445
20446 case eeSPINTILE:
20447 e = new eSpinTile((zfix)x,(zfix)y,id,clk);
20448 break;
20449
20450 // and these enemies use the misc10/misc2 value
20451 case eeROCK:
20452 {
20453 switch(guysbuf[id&0xFFF].misc10)
20454 {
20455 case 1:
20456 e = new eBoulder((zfix)x,(zfix)y,id,clk);
20457 break;
20458
20459 case 0:
20460 default:
20461 e = new eRock((zfix)x,(zfix)y,id,clk);
20462 break;
20463 }
20464
20465 break;
20466 }
20467
20468 case eeTRAP:
20469 {
20470 switch(guysbuf[id&0xFFF].misc2)
20471 {
20472 case 1:
20473 e = new eTrap2((zfix)x,(zfix)y,id,clk);
20474 break;
20475
20476 case 0:
20477 default:
20478 e = new eTrap((zfix)x,(zfix)y,id,clk);
20479 break;
20480 }
20481
20482 break;
20483 }
20484
20485 case eeDONGO:
20486 {
20487 switch(guysbuf[id&0xFFF].misc10)
20488 {
20489 case 1:
20490 e = new eDodongo2((zfix)x,(zfix)y,id,clk);
20491 break;
20492
20493 case 0:
20494 default:
20495 e = new eDodongo((zfix)x,(zfix)y,id,clk);
20496 break;
20497 }
20498
20499 break;
20500 }
20501
20502 case eeDIG:
20503 {
20504 switch(guysbuf[id&0xFFF].misc10)
20505 {
20506 case 1:
20507 e = new eLilDig((zfix)x,(zfix)y,id,clk);
20508 break;
20509
20510 case 0:
20511 default:
20512 e = new eBigDig((zfix)x,(zfix)y,id,clk);
20513 break;
20514 }
20515
20516 break;
20517 }
20518
20519 case eePATRA:
20520 {
20521 switch(guysbuf[id&0xFFF].misc10)
20522 {
20523 case 1:
20524 if (get_bit(quest_rules,qr_HARDCODED_BS_PATRA))
20525 {
20526 e = new ePatraBS((zfix)x,(zfix)y,id,clk);
20527 break;
20528 }
20529 [[fallthrough]];
20530 case 0:
20531 default:
20532 e = new ePatra((zfix)x,(zfix)y,id,clk);
20533 break;
20534 }
20535
20536 break;
20537 }
20538
20539 case eeGUY:
20540 {
20541 switch(guysbuf[id&0xFFF].misc10)
20542 {
20543 case 1:
20544 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20545 break;
20546
20547 case 0:
20548 default:
20549 e = new eNPC((zfix)x,(zfix)y,id,clk);
20550 break;
20551 }
20552
20553 break;
20554 }
20555
20556 case eeNONE:
20557 if(guysbuf[id&0xFFF].misc10 ==1)
20558 {
20559 e = new eTrigger((zfix)x,(zfix)y,id,clk);
20560 break;
20561 break;
20562 }
20563 [[fallthrough]];
20564 default:
20565
20566 return 0;
20567 }
20568
20569 407 ret++; // Made one enemy.
20570
20571
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
407 if(z && canfall(id))
20572 {
20573 e->z = (zfix)z;
20574 }
20575
20576
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 407 times.
407 ((enemy*)e)->ceiling = (z && canfall(id));
20577
20578
1/2
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
407 if(!guys.add(e))
20579 {
20580 return 0;
20581 }
20582
20583 // add segments of segmented enemies
20584 407 int32_t c=0;
20585
20586
1/6
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
407 switch(guysbuf[id&0xFFF].family)
20587 {
20588 case eeMOLD:
20589 {
20590 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20591 id &= 0xFFF;
20592
20593 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id].misc1)); i++)
20594 {
20595 //christ this is messy -DD
20596 int32_t segclk = -i*((int32_t)(8.0/(zslongToFix(guysbuf[id&0xFFF].step*100))));
20597
20598 if(!guys.add(new esMoldorm((zfix)x,(zfix)y,id+0x1000,segclk)))
20599 {
20600 al_trace("Moldorm segment %d could not be created!\n",i+1);
20601
20602 for(int32_t j=0; j<i+1; j++)
20603 guys.del(guys.Count()-1);
20604
20605 return 0;
20606 }
20607
20608 if(i>0)
20609 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20610
20611 ret++;
20612 }
20613
20614 break;
20615 }
20616
20617 case eeLANM:
20618 {
20619 id &= 0xFFF;
20620 int32_t shft = guysbuf[id].misc2;
20621 byte is=((enemy*)guys.spr(guys.Count()-1))->item_set;
20622
20623 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x1000,0)))
20624 {
20625 al_trace("Lanmola segment 1 could not be created!\n");
20626 guys.del(guys.Count()-1);
20627 return 0;
20628 }
20629
20630 ret++;
20631
20632 for(int32_t i=1; i<zc_max(1,zc_min(253,guysbuf[id&0xFFF].misc1)); i++)
20633 {
20634 if(!guys.add(new esLanmola((zfix)x,(zfix)y,id+0x2000,-(i<<shft))))
20635 {
20636 al_trace("Lanmola segment %d could not be created!\n",i+1);
20637
20638 for(int32_t j=0; j<i+1; j++)
20639 guys.del(guys.Count()-1);
20640
20641 return 0;
20642 }
20643
20644 ((enemy*)guys.spr(guys.Count()-1))->item_set=is;
20645 ret++;
20646 }
20647 }
20648 break;
20649
20650 case eeMANHAN:
20651 id &= 0xFFF;
20652
20653 for(int32_t i=0; i<((!(guysbuf[id].misc2))?4:8); i++)
20654 {
20655 if(!guys.add(new esManhandla((zfix)x,(zfix)y,id+0x1000,i)))
20656 {
20657 al_trace("Manhandla head %d could not be created!\n",i+1);
20658
20659 for(int32_t j=0; j<i+1; j++)
20660 {
20661 guys.del(guys.Count()-1);
20662 }
20663
20664 return 0;
20665 }
20666
20667 ret++;
20668 ((enemy*)guys.spr(guys.Count()-1))->frate=guysbuf[id].misc1;
20669 }
20670
20671 break;
20672
20673 case eeGLEEOK:
20674 {
20675 id &= 0xFFF;
20676
20677 for(int32_t i=0; i<zc_max(1,zc_min(254,guysbuf[id&0xFFF].misc1)); i++)
20678 {
20679 if(!guys.add(new esGleeok((zfix)x,(zfix)y,id+0x1000,c, e)))
20680 {
20681 al_trace("Gleeok head %d could not be created!\n",i+1);
20682
20683 for(int32_t j=0; j<i+1; j++)
20684 {
20685 guys.del(guys.Count()-1);
20686 }
20687
20688 return false;
20689 }
20690
20691 c-=guysbuf[id].misc4;
20692 ret++;
20693 }
20694 }
20695 break;
20696
20697
20698 case eePATRA:
20699 {
20700 id &= 0xFFF;
20701 int32_t outeyes = 0;
20702
20703 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc1); i++)
20704 {
20705 if(!((guysbuf[id].misc10&&get_bit(quest_rules,qr_HARDCODED_BS_PATRA))?guys.add(new esPatraBS((zfix)x,(zfix)y,id+0x1000,i,e)):guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e))))
20706 {
20707 al_trace("Patra outer eye %d could not be created!\n",i+1);
20708
20709 for(int32_t j=0; j<i+1; j++)
20710 guys.del(guys.Count()-1);
20711
20712 return 0;
20713 }
20714 else
20715 outeyes++;
20716
20717 ret++;
20718 }
20719
20720 for(int32_t i=0; i<zc_min(254,guysbuf[id&0xFFF].misc2); i++)
20721 {
20722 if(!guys.add(new esPatra((zfix)x,(zfix)y,id+0x1000,i,e)))
20723 {
20724 al_trace("Patra inner eye %d could not be created!\n",i+1);
20725
20726 for(int32_t j=0; j<i+1+zc_min(254,outeyes); j++)
20727 guys.del(guys.Count()-1);
20728
20729 return 0;
20730 }
20731
20732 ret++;
20733 }
20734
20735 break;
20736 }
20737 }
20738
20739 407 return ret;
20740 407 }
20741
20742 25244 bool isjumper(int32_t id)
20743 {
20744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25244 times.
25244 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20745 {
20746 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "isjumper()");
20747 return false;
20748 }
20749
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 25244 times.
25244 switch(guysbuf[id&0xFFF].family)
20750 {
20751 case eeROCK:
20752 case eeTEK:
20753 return true;
20754
20755 case eeWALK:
20756
2/4
✓ Branch 0 taken 25244 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25244 times.
25244 if(guysbuf[id&0xFFF].misc9==e9tVIRE || guysbuf[id&0xFFF].misc9==e9tPOLSVOICE) return true;
20757 25244 }
20758
20759 25244 return false;
20760 25244 }
20761
20762
20763 356 bool isfixedtogrid(int32_t id)
20764 {
20765
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 356 times.
356 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20766 {
20767 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "isfixedtogrid()");
20768 return false;
20769 }
20770
1/2
✓ Branch 0 taken 356 times.
✗ Branch 1 not taken.
356 switch(guysbuf[id&0xFFF].family)
20771 {
20772 case eeWALK:
20773 case eeLEV:
20774 case eeZORA:
20775 case eeDONGO:
20776 case eeGANON:
20777 case eeROCK:
20778 case eeGLEEOK:
20779 case eeAQUA:
20780 case eeLANM:
20781 return true;
20782 }
20783
20784 356 return false;
20785 356 }
20786
20787 // Can't fall, can have Z value.
20788 364889 bool isflier(int32_t id)
20789 {
20790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 364889 times.
364889 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20791 {
20792 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "isflier()");
20793 return false;
20794 }
20795
2/2
✓ Branch 0 taken 332289 times.
✓ Branch 1 taken 32600 times.
364889 switch(guysbuf[id&0xFFF].family) //id&0x0FFF)
20796 {
20797 case eePEAHAT:
20798 case eeKEESE:
20799 case eePATRA:
20800 case eeFAIRY:
20801 case eeGHINI:
20802
20803 // Could theoretically have their Z set by a script
20804 case eeFIRE:
20805 32600 return true;
20806 break;
20807 }
20808
20809 332289 return false;
20810 364889 }
20811
20812 // Can't have Z position
20813 25244 bool never_in_air(int32_t id)
20814 {
20815
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25244 times.
25244 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20816 {
20817 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "never_in_air()");
20818 return false;
20819 }
20820
1/2
✓ Branch 0 taken 25244 times.
✗ Branch 1 not taken.
25244 switch(guysbuf[id&0xFFF].family)
20821 {
20822 case eeMANHAN:
20823 case eeMOLD:
20824 case eeLANM:
20825 case eeGLEEOK:
20826 case eeZORA:
20827 case eeLEV:
20828 case eeAQUA:
20829 case eeROCK:
20830 case eeGANON:
20831 case eeTRAP:
20832 case eePROJECTILE:
20833 case eeSPINTILE:
20834 return true;
20835 }
20836
20837 25244 return false;
20838 25244 }
20839
20840 25244 bool canfall(int32_t id)
20841 {
20842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25244 times.
25244 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20843 {
20844 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "canfall()");
20845 return false;
20846 }
20847
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 25244 times.
✗ Branch 2 not taken.
25244 switch(guysbuf[id&0xFFF].family)
20848 {
20849 case eeGUY:
20850 {
20851 if(id < eOCTO1S)
20852 return false;
20853
20854 switch(guysbuf[id&0xFFF].misc10)
20855 {
20856 case 1:
20857 case 2:
20858 return true;
20859
20860 case 0:
20861 case 3:
20862 default:
20863 return false;
20864 }
20865
20866 case eeGHOMA:
20867 case eeDIG:
20868 return false;
20869 }
20870 }
20871
20872
20873
2/4
✓ Branch 0 taken 25244 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25244 times.
25244 return !never_in_air(id) && !isflier(id) && !isjumper(id);
20874 25244 }
20875
20876 325214 bool enemy::enemycanfall(int32_t id, bool checkgrav)
20877 {
20878
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325214 times.
325214 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
20879 {
20880 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "enemycanfall()");
20881 return false;
20882 }
20883 //Z_scripterrlog("canfall family is %d:\n", family);
20884 //Z_scripterrlog("canfall gravity is %s:\n", moveflags & FLAG_OBEYS_GRAV ? "true" : "false");
20885 //if ( family == eeFIRE && id >= eSTART )
20886 //{
20887 // Z_scripterrlog("eeFire\n");
20888 // return moveflags & FLAG_OBEYS_GRAV; //'Other' enemy class, used by scripts. -Z
20889 //}
20890
20891 //In ZQ, eeFIRE is Other(floating) and eeOTHER is 'other'.
20892
20893
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 311002 times.
✓ Branch 2 taken 14212 times.
325214 switch(guysbuf[id&0xFFF].family)
20894 {
20895 case eeGUY:
20896 {
20897
1/2
✓ Branch 0 taken 14212 times.
✗ Branch 1 not taken.
14212 if(id < eOCTO1S) //screen guys and fires that aren't real enemies, and never fall
20898 14212 return false;
20899
20900 switch(guysbuf[id&0xFFF].misc10) //I'm unsure what these specify off-hand. Needs better comments. -Z
20901 {
20902 case 1:
20903 case 2:
20904 return true;
20905
20906 case 0:
20907 case 3:
20908 default:
20909 return false;
20910 }
20911
20912 case eeGHOMA:
20913 case eeDIG:
20914 return false;
20915 }
20916 }
20917
20918
2/2
✓ Branch 0 taken 192577 times.
✓ Branch 1 taken 118425 times.
311002 if(!checkgrav) return true;
20919 192577 return (moveflags & FLAG_OBEYS_GRAV);
20920
20921 // if ( isflier(id) || isjumper(id) || never_in_air(id) )
20922 // {
20923 // if ( moveflags & FLAG_OBEYS_GRAV ) return true;
20924 // else return false;
20925 // }
20926 // else
20927 // {
20928 // return (moveflags & FLAG_OBEYS_GRAV);
20929 // }
20930 //return !never_in_air(id) && !isflier(id) && !isjumper(id);
20931 325214 }
20932
20933 13 void addfires()
20934 {
20935
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 if(!get_bit(quest_rules,qr_NOGUYFIRES))
20936 {
20937 8 int32_t bs = get_bit(quest_rules,qr_BSZELDA);
20938 8 addguy(bs? 64: 72,64,gFIRE,-17,false);
20939 8 addguy(bs?176:168,64,gFIRE,-18,false);
20940 8 }
20941 13 }
20942
20943 169 void loadguys()
20944 {
20945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 169 times.
169 if(loaded_guys)
20946 return;
20947
20948 169 loaded_guys=true;
20949
20950 169 byte Guy=0;
20951 // When in caves/item rooms, use mSPECIALITEM and ipONETIME2
20952 // Else use mITEM and ipONETIME
20953 169 int32_t mf = (currscr>=128) ? mSPECIALITEM : mITEM;
20954 169 int32_t onetime = (currscr>=128) ? ipONETIME2 : ipONETIME;
20955
20956 169 repaircharge=0;
20957 169 adjustmagic=false;
20958 169 learnslash=false;
20959
20960
2/2
✓ Branch 0 taken 507 times.
✓ Branch 1 taken 169 times.
676 for(int32_t i=0; i<3; i++)
20961 {
20962 507 prices[i]=0;
20963 507 }
20964
20965 169 hasitem=0;
20966
20967
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 157 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 10 times.
169 if(currscr>=128 && DMaps[currdmap].flags&dmfGUYCAVES)
20968 {
20969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(DMaps[currdmap].flags&dmfCAVES)
20970 {
20971 10 Guy=tmpscr[1].guy;
20972 10 }
20973 10 }
20974 else
20975 {
20976 159 Guy=tmpscr->guy;
20977
20978
4/4
✓ Branch 0 taken 157 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 109 times.
✓ Branch 3 taken 48 times.
159 if(currscr < 0x80 && (DMaps[currdmap].flags&dmfVIEWMAP))
20979 48 game->maps[(currmap*MAPSCRSNORMAL)+currscr] |= mVISITED; // mark as visited
20980 }
20981
20982 // The Guy appears if 'Hero is in cave' equals 'Guy is in cave'.
20983
4/4
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 13 times.
169 if(Guy && ((currscr>=128) == !!(DMaps[currdmap].flags&dmfGUYCAVES)))
20984 {
20985
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(tmpscr->room==rZELDA)
20986 {
20987 addguy(120,72,Guy,-15,true);
20988 guys.spr(0)->hxofs=1000;
20989 addenemy(128,96,eFIRE,-15);
20990 addenemy(112,96,eFIRE,-15);
20991 addenemy(96,120,eFIRE,-15);
20992 addenemy(144,120,eFIRE,-15);
20993 return;
20994 }
20995
20996
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13 if(Guy!=gFAIRY || !get_bit(quest_rules,qr_NOFAIRYGUYFIRES))
20997 13 addfires();
20998
20999
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10 times.
13 if(currscr>=128)
21000
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10 if(getmapflag() && !(tmpscr->flags9&fBELOWRETURN))
21001 Guy=0;
21002
21003
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
13 switch(tmpscr->room)
21004 {
21005 case rSP_ITEM:
21006 case rGRUMBLE:
21007 case rBOMBS:
21008 case rARROWS:
21009 case rSWINDLE:
21010 case rMUPGRADE:
21011 case rLEARNSLASH:
21012 case rTAKEONE:
21013 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21014 Guy=0;
21015
21016 break;
21017
21018 case rREPAIR:
21019 if (get_bit(quest_rules, qr_OLD_DOORREPAIR)) break;
21020 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21021 Guy=0;
21022
21023 break;
21024 case rRP_HC:
21025 if (get_bit(quest_rules, qr_OLD_POTION_OR_HC)) break;
21026 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21027 Guy=0;
21028
21029 break;
21030 case rMONEY:
21031 if (get_bit(quest_rules, qr_OLD_SECRETMONEY)) break;
21032 if((get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag((currscr < 128) ? mITEM : mSPECIALITEM)) || (!get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW) && getmapflag() && !(tmpscr->flags9&fBELOWRETURN))) //get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)
21033 Guy=0;
21034
21035 break;
21036
21037 case rTRIFORCE:
21038 {
21039 int32_t tc = TriforceCount();
21040
21041 if(get_bit(quest_rules,qr_4TRI))
21042 {
21043 if((get_bit(quest_rules,qr_3TRI) && tc>=3) || tc>=4)
21044 Guy=0;
21045 }
21046 else
21047 {
21048 if((get_bit(quest_rules,qr_3TRI) && tc>=6) || tc>=8)
21049 Guy=0;
21050 }
21051 }
21052 break;
21053 }
21054
21055
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if(Guy)
21056 {
21057
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13 if(Guy!=gFAIRY || !get_bit(quest_rules,qr_NOFAIRYGUYFIRES))
21058 13 blockpath=true;
21059
21060
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
13 if(currscr<128)
21061 3 sfx(WAV_SCALE);
21062
21063
3/4
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
13 addguy(120,64,Guy, (dlevel||BSZ)?-15:startguy[zc_oldrand()&7], true);
21064 13 Hero.Freeze();
21065 13 }
21066 13 }
21067
1/2
✓ Branch 0 taken 156 times.
✗ Branch 1 not taken.
156 else if(Guy==gFAIRY) // The only Guy that somewhat ignores the "Guys In Caves Only" DMap flag
21068 {
21069 sfx(WAV_SCALE);
21070 addguy(120,62,gFAIRY,-14,false);
21071 }
21072
21073 169 loaditem();
21074
21075 // Collecting a rupee in a '10 Rupees' screen sets the mITEM screen state if
21076 // it doesn't appear in a Cave/Item Cellar, and the mSPECIALITEM screen state if it does.
21077
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 169 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
169 if(tmpscr->room==r10RUPIES && !getmapflag(mf))
21078 {
21079 //setmapflag();
21080 for(int32_t i=0; i<10; i++)
21081 additem(ten_rupies_x[i],ten_rupies_y[i],0,ipBIGRANGE+onetime,-14);
21082 }
21083 169 }
21084
21085 169 void loaditem()
21086 {
21087 169 byte Item = 0;
21088
21089
2/2
✓ Branch 0 taken 157 times.
✓ Branch 1 taken 12 times.
169 if(currscr<128)
21090 {
21091 157 Item=tmpscr->item;
21092
21093
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 149 times.
✓ Branch 2 taken 126 times.
✓ Branch 3 taken 31 times.
157 if((!getmapflag(mITEM) || (tmpscr->flags9&fITEMRETURN)) && (tmpscr->hasitem != 0))
21094 {
21095
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(tmpscr->flags8&fSECRETITEM)
21096 hasitem=8;
21097
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 11 times.
31 else if(tmpscr->flags&fITEM)
21098 20 hasitem=1;
21099
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8 times.
11 else if(tmpscr->enemyflags&efCARRYITEM)
21100 3 hasitem=4; // Will be set to 2 by roaming_item
21101 else
21102
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
16 items.add(new item((zfix)tmpscr->itemx,
21103
4/14
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 8 times.
✗ Branch 13 not taken.
8 (tmpscr->flags7&fITEMFALLS && isSideViewGravity()) ? (zfix)-170 : (zfix)tmpscr->itemy+(get_bit(quest_rules, qr_NOITEMOFFSET)?0:1),
21104
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
8 (tmpscr->flags7&fITEMFALLS && !(isSideViewGravity())) ? (zfix)170 : (zfix)0,
21105
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 Item,ipONETIME|ipBIGRANGE|((itemsbuf[Item].family==itype_triforcepiece ||
21106 8 (tmpscr->flags3&fHOLDITEM)) ? ipHOLDUP : 0) | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0),0));
21107 31 }
21108 157 }
21109
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
12 else if(!(DMaps[currdmap].flags&dmfCAVES))
21110 {
21111
2/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2 if((!getmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM) || (tmpscr[1].flags9&fBELOWRETURN)) && tmpscr[1].room==rSP_ITEM
21112
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
2 && (currscr==128 || !get_bit(quest_rules,qr_ITEMSINPASSAGEWAYS)))
21113 {
21114 1 Item=tmpscr[1].catchall;
21115
21116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(Item)
21117
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 items.add(new item((zfix)tmpscr->itemx,
21118
4/14
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
1 (tmpscr->flags7&fITEMFALLS && isSideViewGravity()) ? (zfix)-170 : (zfix)tmpscr->itemy+(get_bit(quest_rules, qr_NOITEMOFFSET)?0:1),
21119
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
1 (tmpscr->flags7&fITEMFALLS && !(isSideViewGravity())) ? (zfix)170 : (zfix)0,
21120 1 Item,ipONETIME2|ipBIGRANGE|ipHOLDUP | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0),0));
21121 1 }
21122 2 }
21123 169 }
21124
21125 2 void never_return(int32_t index)
21126 {
21127
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!get_bit(quest_rules,qr_KILLALL))
21128 1 goto doit;
21129
21130
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for(int32_t i=0; i<guys.Count(); i++)
21131
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if(((((enemy*)guys.spr(i))->d->flags)&guy_neverret) && i!=index)
21132 {
21133 goto dontdoit;
21134 1 }
21135
21136 doit:
21137 2 setmapflag(mNEVERRET);
21138 dontdoit:
21139 2 return;
21140 }
21141
21142 352 bool slowguy(int32_t id)
21143 {
21144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 352 times.
352 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
21145 {
21146 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "slowguy()");
21147 return false;
21148 }
21149 //return (guysbuf[id].step<100);
21150
2/2
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 120 times.
352 switch(id)
21151 {
21152 case eOCTO1S:
21153 case eOCTO2S:
21154 case eOCTO1F:
21155 case eOCTO2F:
21156 case eLEV1:
21157 case eLEV2:
21158 case eROCK:
21159 case eBOULDER:
21160 120 return true;
21161 }
21162
21163 232 return false;
21164 352 }
21165
21166 380 bool ok2add(int32_t id)
21167 {
21168
2/4
✓ Branch 0 taken 380 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 380 times.
380 if( ((unsigned)(id&0xFFF)) > MAXGUYS || id <= 0)
21169 {
21170 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "oktoadd()");
21171 return false;
21172 }
21173
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
380 if(getmapflag(mNEVERRET) && (guysbuf[id].flags & guy_neverret))
21174 return false;
21175
21176
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
380 switch(guysbuf[id].family)
21177 {
21178 // I added a special case for shooters because having traps on the same screen
21179 // was preventing them from spawning due to TMPNORET. This means they will
21180 // never stay dead, though, so it may not be the best solution. - Saf
21181 case eePROJECTILE:
21182 return true;
21183
21184
21185 case eeDIG:
21186 {
21187 switch(guysbuf[id].misc10)
21188 {
21189 case 1:
21190 if(!get_bit(quest_rules,qr_NOTMPNORET))
21191 return !getmapflag(mTMPNORET);
21192
21193 return true;
21194
21195 case 0:
21196 default:
21197 return true;
21198 }
21199 }
21200 case eeGANON:
21201 case eeTRAP:
21202 if ((guysbuf[id].family == eeGANON && !get_bit(quest_rules, qr_CAN_PLACE_GANON))
21203 || (guysbuf[id].family == eeTRAP && !get_bit(quest_rules, qr_CAN_PLACE_TRAPS))) return false;
21204 [[fallthrough]];
21205 default:
21206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 380 times.
380 if (guysbuf[id].flags2&guy_ignoretmpnr) return true;
21207 380 break;
21208 }
21209
21210
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 168 times.
380 if(!get_bit(quest_rules,qr_NOTMPNORET))
21211 168 return !getmapflag(mTMPNORET);
21212
21213 212 return true;
21214 380 }
21215
21216 1854 void activate_fireball_statue(int32_t pos)
21217 {
21218
3/4
✓ Branch 0 taken 352 times.
✓ Branch 1 taken 1502 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 352 times.
1854 if(!(tmpscr->enemyflags&efFIREBALLS) || statueID<0)
21219 {
21220 1502 return;
21221 }
21222
21223 352 int32_t cx=-1000, cy=-1000;
21224 352 int32_t x = (pos&15)<<4;
21225 352 int32_t y = pos&0xF0;
21226
21227 352 int32_t ctype = combobuf[MAPCOMBO(x,y)].type;
21228
21229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 352 times.
352 if(!isfixedtogrid(statueID))
21230 {
21231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 352 times.
352 if(ctype==cL_STATUE)
21232 {
21233 cx=x+4;
21234 cy=y+7;
21235 }
21236
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 348 times.
352 else if(ctype==cR_STATUE)
21237 {
21238 4 cx=x-8;
21239 4 cy=y-1;
21240 4 }
21241
1/2
✓ Branch 0 taken 348 times.
✗ Branch 1 not taken.
348 else if(ctype==cC_STATUE)
21242 {
21243 cx=x;
21244 cy=y;
21245 }
21246 352 }
21247 else if(ctype==cL_STATUE || ctype==cR_STATUE || ctype==cC_STATUE)
21248 {
21249 cx=x;
21250 cy=y;
21251 }
21252
21253
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 4 times.
352 if(cx!=-1000) // No point creating it if this is false
21254 {
21255
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 for(int32_t j=0; j<guys.Count(); j++)
21256 {
21257
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy))
21258 {
21259 if((guys.spr(j)->id&0xFFF) == statueID) // There's already a matching enemy here!
21260 return; // No point deleting it. A script might be toying with it in some way.
21261 else
21262 guys.del(j);
21263 }
21264 2 }
21265
21266 4 addenemy(cx, cy, statueID, !isfixedtogrid(statueID) ? 24 : 0);
21267 4 }
21268 1854 }
21269
21270 169 void activate_fireball_statues()
21271 {
21272
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 167 times.
169 if(!(tmpscr->enemyflags&efFIREBALLS))
21273 {
21274 167 return;
21275 }
21276
21277
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 352 times.
354 for(int32_t i=0; i<176; i++)
21278 {
21279 352 activate_fireball_statue(i);
21280 352 }
21281 169 }
21282
21283 169 void load_default_enemies()
21284 {
21285 169 wallm_load_clk=frame-80;
21286 169 int32_t Id=0;
21287
21288
2/2
✓ Branch 0 taken 159 times.
✓ Branch 1 taken 10 times.
169 if(tmpscr->enemyflags&efZORA)
21289 {
21290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(zoraID>=0)
21291 10 addenemy(-16, -16, zoraID, 0);
21292 10 }
21293
21294
1/2
✓ Branch 0 taken 169 times.
✗ Branch 1 not taken.
169 if(tmpscr->enemyflags&efTRAP4)
21295 {
21296 if(cornerTrapID>=0)
21297 {
21298 addenemy(32, 32, cornerTrapID, -14);
21299 addenemy(208, 32, cornerTrapID, -14);
21300 addenemy(32, 128, cornerTrapID, -14);
21301 addenemy(208, 128, cornerTrapID, -14);
21302 }
21303 }
21304
21305
2/2
✓ Branch 0 taken 1859 times.
✓ Branch 1 taken 169 times.
2028 for(int32_t y=0; y<176; y+=16)
21306 {
21307
2/2
✓ Branch 0 taken 29744 times.
✓ Branch 1 taken 1859 times.
31603 for(int32_t x=0; x<256; x+=16)
21308 {
21309 29744 int32_t ctype = combobuf[MAPCOMBO(x,y)].type;
21310 29744 int32_t cflag = MAPFLAG(x, y);
21311 29744 int32_t cflag_i = MAPCOMBOFLAG(x, y);
21312
21313
3/6
✓ Branch 0 taken 29744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29744 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29744 times.
29744 if(ctype==cTRAP_H || cflag==mfTRAP_H || cflag_i==mfTRAP_H)
21314 {
21315 if(trapLOSHorizontalID>=0)
21316 addenemy(x, y, trapLOSHorizontalID, -14);
21317 }
21318
3/6
✓ Branch 0 taken 29744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29744 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29744 times.
29744 else if(ctype==cTRAP_V || cflag==mfTRAP_V || cflag_i==mfTRAP_V)
21319 {
21320 if(trapLOSVerticalID>=0)
21321 addenemy(x, y, trapLOSVerticalID, -14);
21322 }
21323
3/6
✓ Branch 0 taken 29744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29744 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29744 times.
29744 else if(ctype==cTRAP_4 || cflag==mfTRAP_4 || cflag_i==mfTRAP_4)
21324 {
21325 if(trapLOS4WayID>=0)
21326 {
21327 if(addenemy(x, y, trapLOS4WayID, -14))
21328 guys.spr(guys.Count()-1)->dummy_int[1]=2;
21329 }
21330 }
21331
21332
3/6
✓ Branch 0 taken 29744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29744 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29744 times.
29744 else if(ctype==cTRAP_LR || cflag==mfTRAP_LR || cflag_i==mfTRAP_LR)
21333 {
21334 if(trapConstantHorizontalID>=0)
21335 addenemy(x, y, trapConstantHorizontalID, -14);
21336 }
21337
3/6
✓ Branch 0 taken 29744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29744 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29744 times.
29744 else if(ctype==cTRAP_UD || cflag==mfTRAP_UD || cflag_i==mfTRAP_UD)
21338 {
21339 if(trapConstantVerticalID>=0)
21340 addenemy(x, y, trapConstantVerticalID, -14);
21341 }
21342
21343
1/2
✓ Branch 0 taken 29744 times.
✗ Branch 1 not taken.
29744 if(ctype==cSPINTILE1)
21344 {
21345 // Awaken spinning tile
21346 awaken_spinning_tile(tmpscr,COMBOPOS(x,y));
21347 }
21348 29744 }
21349 1859 }
21350
21351
1/2
✓ Branch 0 taken 169 times.
✗ Branch 1 not taken.
169 if(tmpscr->enemyflags&efTRAP2)
21352 {
21353 if(centerTrapID>=-1)
21354 {
21355 if(addenemy(64, 80, centerTrapID, -14))
21356 guys.spr(guys.Count()-1)->dummy_int[1]=1;
21357
21358 if(addenemy(176, 80, centerTrapID, -14))
21359 guys.spr(guys.Count()-1)->dummy_int[1]=1;
21360 }
21361 }
21362
21363
1/2
✓ Branch 0 taken 169 times.
✗ Branch 1 not taken.
169 if(tmpscr->enemyflags&efROCKS)
21364 {
21365 if(rockID>=0)
21366 {
21367 addenemy(zc_oldrand()&0xF0, 0, rockID, 0);
21368 addenemy(zc_oldrand()&0xF0, 0, rockID, 0);
21369 addenemy(zc_oldrand()&0xF0, 0, rockID, 0);
21370 }
21371 }
21372
21373 169 activate_fireball_statues();
21374 169 }
21375
21376 208478 void update_slope_combopos(int32_t lyr, int32_t pos)
21377 {
21378
2/4
✓ Branch 0 taken 208478 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 208478 times.
208478 if(unsigned(lyr) > 6 || unsigned(pos) > 175) return;
21379 208478 mapscr* s = FFCore.tempScreens[lyr];
21380 208478 newcombo const& cmb = combobuf[s->data[pos]];
21381
21382 208478 auto id = (176*lyr)+pos;
21383 208478 auto it = slopes.find(id);
21384
21385 208478 bool wasSlope = it!=slopes.end();
21386 208478 bool isSlope = cmb.type == cSLOPE;
21387
21388
3/4
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 208408 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 70 times.
208478 if(isSlope && !wasSlope)
21389 {
21390 70 slopes.try_emplace(id, &(s->data[pos]), nullptr, id, pos);
21391 70 }
21392
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 208408 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
208408 else if(wasSlope && !isSlope)
21393 {
21394 slopes.erase(it);
21395 }
21396 208478 }
21397 169 void update_slope_comboposes()
21398 {
21399
2/2
✓ Branch 0 taken 1183 times.
✓ Branch 1 taken 169 times.
1352 for(auto lyr = 0; lyr < 7; ++lyr)
21400 {
21401
2/2
✓ Branch 0 taken 208208 times.
✓ Branch 1 taken 1183 times.
209391 for(auto pos = 0; pos < 176; ++pos)
21402 208208 update_slope_combopos(lyr,pos);
21403 1183 }
21404 169 }
21405
21406 // Everything that must be done before we change a screen's combo to another combo, or a combo's type to another type.
21407 // There's 2 routines because it's unclear if combobuf or tmpscr->data gets modified. -L
21408 1502 void screen_combo_modify_preroutine(mapscr *s, int32_t pos)
21409 {
21410 1502 delete_fireball_shooter(s, pos);
21411 1502 }
21412
21413 //Placeholder in case we need it.
21414 void screen_ffc_modify_preroutine(word index)
21415 {
21416 return;
21417 }
21418
21419 // Everything that must be done after we change a screen's combo to another combo. -L
21420 1502 void screen_combo_modify_postroutine(mapscr *s, int32_t pos)
21421 {
21422 1502 s->valid |= mVALID;
21423 1502 activate_fireball_statue(pos);
21424
21425
1/2
✓ Branch 0 taken 1502 times.
✗ Branch 1 not taken.
1502 if(combobuf[s->data[pos]].type==cSPINTILE1)
21426 {
21427 // Awaken spinning tile
21428 awaken_spinning_tile(s,pos);
21429 }
21430 1502 int32_t lyr = -1;
21431
2/2
✓ Branch 0 taken 1232 times.
✓ Branch 1 taken 270 times.
1502 if(s == tmpscr) lyr = 0;
21432
2/2
✓ Branch 0 taken 1232 times.
✓ Branch 1 taken 7392 times.
8624 else for(size_t q = 0; q < 6; ++q)
21433 {
21434
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7392 times.
7392 if(s == tmpscr2+q)
21435 {
21436 lyr = q+1;
21437 break;
21438 }
21439 7392 }
21440
2/2
✓ Branch 0 taken 1232 times.
✓ Branch 1 taken 270 times.
1502 if(lyr > -1)
21441 270 update_slope_combopos(lyr,pos);
21442 1502 }
21443
21444 24713 void screen_ffc_modify_postroutine(word index)
21445 {
21446 24713 ffcdata& ff = tmpscr->ffcs[index];
21447 24713 newcombo const& cmb = combobuf[ff.getData()];
21448
21449 24713 auto id = (176*7)+int32_t(index);
21450 24713 auto it = slopes.find(id);
21451
21452 24713 bool wasSlope = it!=slopes.end();
21453
2/2
✓ Branch 0 taken 24611 times.
✓ Branch 1 taken 102 times.
24713 bool isSlope = cmb.type == cSLOPE && !(ff.flags&ffCHANGER);
21454
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 24621 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 92 times.
24713 if(isSlope && !wasSlope)
21455 {
21456 92 slopes.try_emplace(id, nullptr, &ff, id);
21457 92 }
21458
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 24620 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
24621 else if(wasSlope && !isSlope)
21459 {
21460 1 slopes.erase(it);
21461 1 }
21462 24713 }
21463
21464 void screen_combo_modify_pre(int32_t cid)
21465 {
21466 for(auto lyr = 0; lyr < 7; ++lyr)
21467 {
21468 mapscr* t = FFCore.tempScreens[lyr];
21469 for(int32_t i = 0; i < 176; i++)
21470 {
21471 if(t->data[i] == cid)
21472 {
21473 screen_combo_modify_preroutine(t,i);
21474 }
21475 }
21476 }
21477 }
21478 void screen_combo_modify_post(int32_t cid)
21479 {
21480 for(auto lyr = 0; lyr < 7; ++lyr)
21481 {
21482 mapscr* t = FFCore.tempScreens[lyr];
21483 for(int32_t i = 0; i < 176; i++)
21484 {
21485 if(t->data[i] == cid)
21486 {
21487 screen_combo_modify_postroutine(t,i);
21488 }
21489 }
21490 }
21491 for(word ind = 0; ind < MAXFFCS; ++ind)
21492 {
21493 if(tmpscr->ffcs[ind].getData() == cid)
21494 screen_ffc_modify_postroutine(ind);
21495 }
21496 }
21497
21498 void awaken_spinning_tile(mapscr *s, int32_t pos)
21499 {
21500 addenemy((pos&15)<<4,pos&0xF0,(s->cset[pos]<<12)+eSPINTILE1,combobuf[s->data[pos]].o_tile+zc_max(1,combobuf[s->data[pos]].frames));
21501 }
21502
21503
21504 // It stands for next_side_pos
21505 128 void nsp(bool random)
21506 // moves sle_x and sle_y to the next position
21507 {
21508
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 50 times.
128 if(random)
21509 {
21510
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 40 times.
78 if(zc_oldrand()%2)
21511 {
21512 38 sle_x = (zc_oldrand()%2) ? 0 : 240;
21513 38 sle_y = (zc_oldrand()%10)*16;
21514 38 }
21515 else
21516 {
21517 40 sle_y = (zc_oldrand()%2) ? 0 : 160;
21518 40 sle_x = (zc_oldrand()%15)*16;
21519 }
21520
21521 78 return;
21522 }
21523
21524
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 22 times.
50 if(sle_x==0)
21525 {
21526
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2 times.
22 if(sle_y<160)
21527 20 sle_y+=16;
21528 else
21529 2 sle_x+=16;
21530 22 }
21531
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
28 else if(sle_y==160)
21532 {
21533
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 1 times.
24 if(sle_x<240)
21534 23 sle_x+=16;
21535 else
21536 1 sle_y-=16;
21537 24 }
21538
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 else if(sle_x==240)
21539 {
21540
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if(sle_y>0)
21541 4 sle_y-=16;
21542 else
21543 sle_x-=16;
21544 4 }
21545 else if(sle_y==0)
21546 {
21547 if(sle_x>0)
21548 sle_x-=16;
21549 else
21550 sle_y+=16;
21551 }
21552 128 }
21553
21554 30 int32_t next_side_pos(bool random)
21555 // moves sle_x and sle_y to the next available position
21556 // returns the direction the enemy should face
21557 {
21558 bool blocked;
21559 30 int32_t c=0;
21560
21561 30 do
21562 {
21563
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 nsp(c>35 ? false : random);
21564
3/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 98 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
158 blocked = _walkflag(sle_x,sle_y,2) || _walkflag(sle_x,sle_y+8,2) ||
21565
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 (combo_class_buf[COMBOTYPE(sle_x,sle_y)].block_enemies ||
21566
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
30 MAPFLAG(sle_x,sle_y) == mfNOENEMY || MAPCOMBOFLAG(sle_x,sle_y)==mfNOENEMY ||
21567
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 MAPFLAG(sle_x,sle_y) == mfNOGROUNDENEMY || MAPCOMBOFLAG(sle_x,sle_y)==mfNOGROUNDENEMY ||
21568 30 iswaterex(MAPCOMBO(sle_x,sle_y), currmap, currscr, -1, sle_x, sle_y, true));
21569
21570
1/2
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
128 if(++c>50)
21571 return -1;
21572
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 30 times.
128 }
21573 128 while(blocked);
21574
21575 30 int32_t dir=0;
21576
21577
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 9 times.
30 if(sle_x==0) dir=right;
21578
21579
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 1 times.
30 if(sle_y==0) dir=down;
21580
21581
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
30 if(sle_x==240) dir=left;
21582
21583
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if(sle_y==168) dir=up;
21584
21585 30 return dir;
21586 30 }
21587
21588 bool can_side_load(int32_t id)
21589 {
21590 if( ((unsigned)(id&0xFFF)) > MAXGUYS )
21591 {
21592 //zprint2("Invalid enemy ID (%d) passed to %s\n", id, "can_side_load()");
21593 return false;
21594 }
21595 switch(guysbuf[id].family) //id&0x0FFF)
21596 {
21597 //case eTEK1:
21598 //case eTEK2:
21599 //case eTEK3:
21600 //case eLEV1:
21601 //case eLEV2:
21602 //case eLEV3:
21603 //case eRAQUAM:
21604 //case eLAQUAM:
21605 //case eDODONGO:
21606 //case eMANHAN:
21607 //case eGLEEOK1:
21608 //case eGLEEOK2:
21609 //case eGLEEOK3:
21610 //case eGLEEOK4:
21611 //case eDIG1:
21612 //case eDIG3:
21613 //case eGOHMA1:
21614 //case eGOHMA2:
21615 //case eCENT1:
21616 //case eCENT2:
21617 //case ePATRA1:
21618 //case ePATRA2:
21619 //case eGANON:
21620 //case eMANHAN2:
21621 //case eCEILINGM: later
21622 //case eFLOORM: later
21623 //case ePATRABS:
21624 //case ePATRAL2:
21625 //case ePATRAL3:
21626 //case eGLEEOK1F:
21627 //case eGLEEOK2F:
21628 //case eGLEEOK3F:
21629 //case eGLEEOK4F:
21630 //case eDODONGOBS:
21631 //case eDODONGOF:
21632 //case eGOHMA3:
21633 //case eGOHMA4:
21634 //case eSHOOTMAGIC:
21635 //case eSHOOTROCK:
21636 //case eSHOOTSPEAR:
21637 //case eSHOOTSWORD:
21638 //case eSHOOTFLAME:
21639 //case eSHOOTFLAME2:
21640 //case eSHOOTFBALL:
21641 case eeTEK:
21642 case eeLEV:
21643 case eeAQUA:
21644 case eeDONGO:
21645 case eeMANHAN:
21646 case eeGLEEOK:
21647 case eeDIG:
21648 case eeGHOMA:
21649 case eeLANM:
21650 case eePATRA:
21651 case eeGANON:
21652 case eePROJECTILE:
21653 return false;
21654 break;
21655 }
21656
21657 return true;
21658 }
21659
21660 static bool script_sle = false;
21661 static int32_t sle_pattern = 0;
21662 void script_side_load_enemies()
21663 {
21664 if(script_sle || sle_clk) return;
21665 sle_cnt = 0;
21666 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21667 ++sle_cnt;
21668 script_sle = true;
21669 sle_pattern = tmpscr->pattern;
21670 sle_clk = 0;
21671 }
21672
21673 671 void side_load_enemies()
21674 {
21675
3/4
✓ Branch 0 taken 671 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 664 times.
✓ Branch 3 taken 7 times.
671 if(!script_sle && sle_clk==0)
21676 {
21677 7 sle_pattern = tmpscr->pattern;
21678 7 sle_cnt = 0;
21679 7 int32_t guycnt = 0;
21680 7 int16_t s = (currmap<<7)+currscr;
21681 7 bool beenhere=false;
21682 7 bool reload=true;
21683 7 bool unbeatablereload = true;
21684
21685 7 load_default_enemies();
21686
21687
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 7 times.
49 for(int32_t i=0; i<6; i++)
21688
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 if(visited[i]==s)
21689 beenhere=true;
21690
21691
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if(!beenhere)
21692 {
21693 7 visited[vhead]=s;
21694 7 vhead = (vhead+1)%6;
21695 7 }
21696 else if(game->guys[s]==0)
21697 {
21698 sle_cnt=0;
21699 reload=false;
21700 }
21701
21702
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if(reload)
21703 {
21704 7 sle_cnt = game->guys[s];
21705
21706
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if((get_bit(quest_rules, qr_NO_LEAVE_ONE_ENEMY_ALIVE_TRICK) && !beenhere)
21707
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
7 || sle_cnt==0)
21708 {
21709
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 7 times.
35 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21710 28 ++sle_cnt;
21711 7 }
21712
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 if (!beenhere && get_bit(quest_rules, qr_UNBEATABLES_DONT_KEEP_DEAD))
21713 {
21714 for(int32_t i = 0; i<sle_cnt && tmpscr->enemy[i]>0; i++)
21715 {
21716 if (!(guysbuf[tmpscr->enemy[i]].flags & guy_doesntcount))
21717 {
21718 unbeatablereload = false;
21719 }
21720 }
21721 if (unbeatablereload)
21722 {
21723 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21724 {
21725 ++sle_cnt;
21726 }
21727 }
21728 }
21729 7 }
21730
21731
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 if((get_bit(quest_rules,qr_ALWAYSRET)) || (tmpscr->flags3&fENEMIESRETURN))
21732 {
21733 sle_cnt = 0;
21734
21735 while(sle_cnt<10 && tmpscr->enemy[sle_cnt]!=0)
21736 ++sle_cnt;
21737 }
21738
21739
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 7 times.
35 for(int32_t i=0; i<sle_cnt; i++)
21740 28 ++guycnt;
21741
21742 7 game->guys[s] = guycnt;
21743 7 }
21744
21745
2/2
✓ Branch 0 taken 641 times.
✓ Branch 1 taken 30 times.
671 if((++sle_clk+8)%24 == 0)
21746 {
21747 30 int32_t dir = next_side_pos(sle_pattern==pSIDESR);
21748
21749
3/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 27 times.
30 if(dir==-1 || tooclose(sle_x,sle_y,32))
21750 {
21751 3 return;
21752 }
21753
21754 27 int32_t enemy_slot=guys.Count();
21755
21756
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
27 while(sle_cnt > 0 && !ok2add(tmpscr->enemy[sle_cnt-1]))
21757 sle_cnt--;
21758
21759
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if(sle_cnt > 0)
21760 {
21761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if(addenemy(sle_x,sle_y,tmpscr->enemy[--sle_cnt],0))
21762 {
21763
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 if (((enemy*)guys.spr(enemy_slot))->family != eeTEK)
21764 {
21765 27 guys.spr(enemy_slot)->dir = dir;
21766 27 }
21767 27 }
21768 27 }
21769 27 }
21770
21771
2/2
✓ Branch 0 taken 662 times.
✓ Branch 1 taken 6 times.
668 if(sle_cnt<=0)
21772 {
21773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if(script_sle)
21774 script_sle = false;
21775 6 else loaded_enemies=true;
21776 6 sle_clk = 0;
21777 6 }
21778 671 }
21779
21780 27815 bool is_starting_pos(int32_t i, int32_t x, int32_t y, int32_t t)
21781 {
21782
21783
4/4
✓ Branch 0 taken 25259 times.
✓ Branch 1 taken 2556 times.
✓ Branch 2 taken 2556 times.
✓ Branch 3 taken 27815 times.
27815 if(tmpscr->enemy[i]<1||tmpscr->enemy[i]>=MAXGUYS) //Hackish fix for crash in Waterford.st on screen 0x65 of dmap 0 (map 1).
21784 {
21785 //zprint2("is_starting_pos(), tmpscr->enemy[i] is: %d\n", tmpscr->enemy[i]);
21786 5112 return false; //never 0, never OoB.
21787 }
21788 // No corner enemies
21789
6/6
✓ Branch 0 taken 23697 times.
✓ Branch 1 taken 4118 times.
✓ Branch 2 taken 994 times.
✓ Branch 3 taken 24691 times.
✓ Branch 4 taken 2840 times.
✓ Branch 5 taken 2272 times.
27815 if((x==0 || x==240) && (y==0 || y==160))
21790
21791 5112 return false;
21792
21793 //Is a no spawn combo...
21794
2/4
✓ Branch 0 taken 24691 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24691 times.
24691 if(MAPFLAG(x+8,y+8)==mfNOENEMYSPAWN || MAPCOMBOFLAG(x+8,y+8)==mfNOENEMYSPAWN)
21795 return false;
21796
21797 // No enemies in dungeon walls
21798
10/10
✓ Branch 0 taken 15948 times.
✓ Branch 1 taken 8743 times.
✓ Branch 2 taken 14108 times.
✓ Branch 3 taken 1840 times.
✓ Branch 4 taken 12268 times.
✓ Branch 5 taken 1840 times.
✓ Branch 6 taken 10060 times.
✓ Branch 7 taken 2208 times.
✓ Branch 8 taken 2208 times.
✓ Branch 9 taken 7852 times.
24691 if(isdungeon() && (x<32 || x>=224 || y<32 || y>=144))
21799 8096 return false;
21800
21801 // Too close
21802
3/4
✓ Branch 0 taken 1527 times.
✓ Branch 1 taken 15068 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1527 times.
16595 if(tooclose(x,y,40) && t<11)
21803 1527 return false;
21804
21805 // Can't fly onto it?
21806
4/4
✓ Branch 0 taken 2517 times.
✓ Branch 1 taken 12551 times.
✓ Branch 2 taken 902 times.
✓ Branch 3 taken 2 times.
15972 if(isflier(tmpscr->enemy[i])&&
21807
1/2
✓ Branch 0 taken 2517 times.
✗ Branch 1 not taken.
2517 (flyerblocked(x+8,y+8,spw_floater,guysbuf[tmpscr->enemy[i]])||
21808
2/2
✓ Branch 0 taken 904 times.
✓ Branch 1 taken 1613 times.
2517 (_walkflag(x,y+8,2)&&!get_bit(quest_rules,qr_WALLFLIERS))))
21809 2 return false;
21810
21811 // Can't jump onto it?
21812 if
21813 (
21814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1118 times.
16184 guysbuf[tmpscr->enemy[i]].family==eeTEK
21815
21816
2/2
✓ Branch 0 taken 1118 times.
✓ Branch 1 taken 13948 times.
15066 &&
21817 (
21818
1/2
✓ Branch 0 taken 1118 times.
✗ Branch 1 not taken.
1118 COMBOTYPE(x+8,y+8)==cNOJUMPZONE||
21819
1/2
✓ Branch 0 taken 1118 times.
✗ Branch 1 not taken.
1118 COMBOTYPE(x+8,y+8)==cNOENEMY||
21820
1/2
✓ Branch 0 taken 1118 times.
✗ Branch 1 not taken.
1118 ispitfall(x+8,y+8)||
21821
1/2
✓ Branch 0 taken 1118 times.
✗ Branch 1 not taken.
1118 MAPFLAG(x+8,y+8)==mfNOENEMY||
21822 1118 MAPCOMBOFLAG(x+8,y+8)==mfNOENEMY
21823 )
21824 )
21825 {
21826 return false;
21827 }
21828
21829 // Other off-limit combos
21830
6/6
✓ Branch 0 taken 12551 times.
✓ Branch 1 taken 2515 times.
✓ Branch 2 taken 11433 times.
✓ Branch 3 taken 1118 times.
✓ Branch 4 taken 7219 times.
✓ Branch 5 taken 4214 times.
26499 if((!isflier(tmpscr->enemy[i])&& guysbuf[tmpscr->enemy[i]].family!=eeTEK &&
21831
2/2
✓ Branch 0 taken 7223 times.
✓ Branch 1 taken 4210 times.
11433 (_walkflag(x,y+8,2) || groundblocked(x+8,y+8,guysbuf[tmpscr->enemy[i]]))) &&
21832 11433 guysbuf[tmpscr->enemy[i]].family!=eeZORA)
21833 4214 return false;
21834
21835 // Don't ever generate enemies on these combos!
21836
2/4
✓ Branch 0 taken 10852 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10852 times.
10852 if(COMBOTYPE(x+8,y+8)==cARMOS||COMBOTYPE(x+8,y+8)==cBSGRAVE)
21837 return false;
21838
21839 //BS Dodongos need at least 2 spaces.
21840
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10852 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
10852 if((guysbuf[tmpscr->enemy[i]].family==eeDONGO)&&(guysbuf[tmpscr->enemy[i]].misc10==1))
21841 {
21842 if(((x<16) ||_walkflag(x-16,y+8, 2))&&
21843 ((x>224)||_walkflag(x+16,y+8, 2))&&
21844 ((y<16) ||_walkflag(x, y-8, 2))&&
21845 ((y>144)||_walkflag(x, y+24,2)))
21846 {
21847 return false;
21848 }
21849 }
21850
21851 10852 return true;
21852 25259 }
21853
21854 706 bool is_ceiling_pattern(int32_t i)
21855 {
21856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 706 times.
706 return (i==pCEILING || i==pCEILINGR);
21857 }
21858
21859 142 int32_t placeenemy(int32_t i)
21860 {
21861 142 std::map<int32_t, int32_t> freeposcache;
21862 142 int32_t frees = 0;
21863
21864
2/2
✓ Branch 0 taken 1562 times.
✓ Branch 1 taken 142 times.
1704 for(int32_t y=0; y<176; y+=16)
21865 {
21866
2/2
✓ Branch 0 taken 24992 times.
✓ Branch 1 taken 1562 times.
26554 for(int32_t x=0; x<256; x+=16)
21867 {
21868
3/4
✓ Branch 0 taken 24992 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10642 times.
✓ Branch 3 taken 14350 times.
24992 if(is_starting_pos(i,x,y,0))
21869 {
21870
1/2
✓ Branch 0 taken 10642 times.
✗ Branch 1 not taken.
10642 freeposcache[frees++] = (y&0xF0)+(x>>4);
21871 10642 }
21872 24992 }
21873 1562 }
21874
21875
1/2
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
142 if(frees > 0)
21876
2/4
✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 142 times.
✗ Branch 3 not taken.
142 return freeposcache[zc_oldrand()%frees];
21877
21878 return -1;
21879 142 }
21880
21881 353 void spawnEnemy(int& pos, int& clk, int& x, int& y, int& fastguys, int& i, int& guycnt, int& loadcnt)
21882 {
21883 353 bool placed=false;
21884 353 int32_t t=-1;
21885
21886 // First: enemy combo flags
21887
2/2
✓ Branch 0 taken 3875 times.
✓ Branch 1 taken 352 times.
4227 for(int32_t sy=0; sy<176; sy+=16)
21888 {
21889
2/2
✓ Branch 0 taken 61993 times.
✓ Branch 1 taken 3874 times.
65867 for(int32_t sx=0; sx<256; sx+=16)
21890 {
21891 61993 int32_t cflag = MAPFLAG(sx, sy);
21892 61993 int32_t cflag_i = MAPCOMBOFLAG(sx, sy);
21893
21894
2/4
✓ Branch 0 taken 61993 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 61993 times.
✗ Branch 3 not taken.
61993 if(((cflag==mfENEMYALL)||(cflag_i==mfENEMYALL)) && (!placed))
21895 {
21896 if(!ok2add(tmpscr->enemy[i]))
21897 {
21898 if (loadcnt < 10 && tmpscr->enemy[i] > 0 && tmpscr->enemy[i] < MAXGUYS) ++loadcnt;
21899 }
21900 else
21901 {
21902 addenemy(sx,
21903 (is_ceiling_pattern(tmpscr->pattern) && isSideViewGravity()) ? -(150+50*guycnt) : sy,
21904 (is_ceiling_pattern(tmpscr->pattern) && !(isSideViewGravity())) ? 150+50*guycnt : 0,tmpscr->enemy[i],-15);
21905
21906 ++guycnt;
21907
21908 placed=true;
21909 goto placed_enemy;
21910 }
21911 }
21912
21913
4/4
✓ Branch 0 taken 61992 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 61992 times.
✓ Branch 3 taken 1 times.
61993 else if(((cflag==mfENEMY0+i)||(cflag_i==mfENEMY0+i)) && (!placed))
21914 {
21915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!ok2add(tmpscr->enemy[i]))
21916 {
21917 if (loadcnt < 10 && tmpscr->enemy[i] > 0 && tmpscr->enemy[i] < MAXGUYS) ++loadcnt;
21918 }
21919 else
21920 {
21921 2 addenemy(sx,
21922
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 (is_ceiling_pattern(tmpscr->pattern) && isSideViewGravity()) ? -(150+50*guycnt) : sy,
21923
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 (is_ceiling_pattern(tmpscr->pattern) && !(isSideViewGravity())) ? 150+50*guycnt : 0,tmpscr->enemy[i],-15);
21924
21925 1 ++guycnt;
21926
21927 1 placed=true;
21928 1 goto placed_enemy;
21929 }
21930 }
21931 61992 }
21932 3874 }
21933
21934 // Next: enemy pattern
21935
6/8
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 219 times.
✓ Branch 2 taken 210 times.
✓ Branch 3 taken 142 times.
✓ Branch 4 taken 210 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 210 times.
352 if((tmpscr->pattern==pRANDOM || tmpscr->pattern==pCEILING) && !(isSideViewGravity()) && ((tmpscr->enemy[i]>0&&tmpscr->enemy[i]<MAXGUYS)))
21936 {
21937 210 do
21938 {
21939
21940 // NES positions
21941 267 pos%=9;
21942 267 x=stx[loadside][pos];
21943 267 y=sty[loadside][pos];
21944 267 ++pos;
21945 267 ++t;
21946
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 210 times.
477 }
21947
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 267 times.
267 while((t< 20) && !is_starting_pos(i,x,y,t));
21948 210 }
21949
21950
3/4
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 210 times.
352 if(t<0 || t >= 20) // above enemy pattern failed
21951 {
21952 // Final chance: find a random position anywhere onscreen
21953 142 int32_t randpos = placeenemy(i);
21954
21955
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142 times.
142 if(randpos>-1)
21956 {
21957 142 x=(randpos&15)<<4;
21958 142 y= randpos&0xF0;
21959 142 }
21960 else // All opportunities failed - abort
21961 {
21962 return;
21963 }
21964 142 }
21965
21966 {
21967 352 int32_t c=0;
21968 352 c=clk;
21969
21970
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 232 times.
352 if(!slowguy(tmpscr->enemy[i]))
21971 232 ++fastguys;
21972
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 109 times.
120 else if(fastguys>0)
21973 11 c=-15*(i-fastguys+2);
21974 else
21975 109 c=-15*(i+1);
21976
21977
4/6
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 305 times.
✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 47 times.
352 if(BSZ&&((tmpscr->enemy[i]>0&&tmpscr->enemy[i]<MAXGUYS))) // Hackish fix for crash in Waterford.qst on screen 0x65 of dmap 0 (map 1).
21978 {
21979 // Special case for blue leevers
21980
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
47 if(guysbuf[tmpscr->enemy[i]].family==eeLEV && guysbuf[tmpscr->enemy[i]].misc1==1)
21981 c=-15*(i+1);
21982 else
21983 47 c=-15;
21984 47 }
21985
21986
1/2
✓ Branch 0 taken 352 times.
✗ Branch 1 not taken.
352 if(!ok2add(tmpscr->enemy[i]))
21987 {
21988 if (loadcnt < 10 && tmpscr->enemy[i] > 0 && tmpscr->enemy[i] < MAXGUYS) ++loadcnt;
21989 }
21990 else
21991 {
21992
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 352 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
352 if(((tmpscr->enemy[i]>0||tmpscr->enemy[i]<MAXGUYS))) // Hackish fix for crash in Waterford.qst on screen 0x65 of dmap 0 (map 1).
21993 {
21994
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 352 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
704 addenemy(x,(is_ceiling_pattern(tmpscr->pattern) && isSideViewGravity()) ? -(150+50*guycnt) : y,
21995
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 352 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
352 (is_ceiling_pattern(tmpscr->pattern) && !(isSideViewGravity())) ? 150+50*guycnt : 0,tmpscr->enemy[i],c);
21996
21997 352 ++guycnt;
21998 352 }
21999 }
22000
22001 352 placed=true;
22002 352 } // if(t < 20)
22003
22004 placed_enemy:
22005
22006 // I don't like this, but it seems to work...
22007 static bool foundCarrier;
22008
22009
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 75 times.
353 if(i==0)
22010 75 foundCarrier=false;
22011
22012
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 353 times.
353 if(placed)
22013 {
22014
3/4
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 278 times.
✓ Branch 2 taken 75 times.
✗ Branch 3 not taken.
353 if(i==0 && tmpscr->enemyflags&efLEADER)
22015 {
22016 int32_t index = guys.idFirst(tmpscr->enemy[i],0xFFF);
22017
22018 if(index!=-1)
22019 {
22020 //grab the first segment. Not accurate to how older versions did it, but the way they did it might be incompatible with enemy editor.
22021 if ((((enemy*)guys.spr(index))->family == eeLANM) && !get_bit(quest_rules, qr_NO_LANMOLA_RINGLEADER)) index = guys.idNth(tmpscr->enemy[i], 2, 0xFFF);
22022 if(index!=-1)
22023 {
22024 ((enemy*)guys.spr(index))->leader = true;
22025 }
22026 }
22027 }
22028
22029
4/4
✓ Branch 0 taken 341 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 338 times.
✓ Branch 3 taken 3 times.
353 if(!foundCarrier && hasitem&(4|2))
22030 {
22031 3 int32_t index = guys.idFirst(tmpscr->enemy[i],0xFFF);
22032
22033
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if(index!=-1 && (((enemy*)guys.spr(index))->flags&guy_doesntcount)==0)
22034 {
22035 3 ((enemy*)guys.spr(index))->itemguy = true;
22036 3 foundCarrier=true;
22037 3 }
22038 3 }
22039 353 }
22040 353 }
22041
22042 bool scriptloadenemies()
22043 {
22044 loaded_enemies = true;
22045 if(script_sle || sle_clk) return false;
22046 if(tmpscr->pattern==pNOSPAWN) return false;
22047
22048 if(tmpscr->pattern==pSIDES || tmpscr->pattern==pSIDESR)
22049 {
22050 script_side_load_enemies();
22051 return true;
22052 }
22053
22054 int32_t pos=zc_oldrand()%9;
22055 int32_t clk=-15,x=0,y=0,fastguys=0;
22056 int32_t i=0,guycnt=0;
22057 int32_t loadcnt = 10;
22058
22059 for(; i<loadcnt && tmpscr->enemy[i]>0; i++)
22060 {
22061 spawnEnemy(pos, clk, x, y, fastguys, i, guycnt, loadcnt);
22062
22063 --clk;
22064 }
22065 return true;
22066 }
22067
22068 80023 void loadenemies()
22069 {
22070
3/4
✓ Branch 0 taken 80023 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 664 times.
✓ Branch 3 taken 79359 times.
80023 if(script_sle || sle_clk)
22071 {
22072 664 side_load_enemies();
22073 664 return;
22074 }
22075
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 79359 times.
79359 if(tmpscr->pattern==pNOSPAWN) return;
22076
2/2
✓ Branch 0 taken 79190 times.
✓ Branch 1 taken 169 times.
79359 if(loaded_enemies)
22077 79190 return;
22078
22079 // check if it's the dungeon boss and it has been beaten before
22080
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
169 if(tmpscr->enemyflags&efBOSS && game->lvlitems[dlevel]&liBOSS)
22081 {
22082 loaded_enemies = true;
22083 return;
22084 }
22085
22086
4/4
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 162 times.
169 if(tmpscr->pattern==pSIDES || tmpscr->pattern==pSIDESR)
22087 {
22088 7 side_load_enemies();
22089 7 return;
22090 }
22091
22092 162 loaded_enemies=true;
22093
22094 // do enemies that are always loaded
22095 162 load_default_enemies();
22096
22097 // dungeon basements
22098
22099 static byte dngn_enemy_x[4] = {32,96,144,208};
22100
22101
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 150 times.
162 if(currscr>=128)
22102 {
22103
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 2 times.
12 if(DMaps[currdmap].flags&dmfCAVES) return;
22104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if ( DMaps[currdmap].flags&dmfNEWCELLARENEMIES )
22105 {
22106 for(int32_t i=0; i<10; i++)
22107 {
22108 if ( tmpscr->enemy[i] )
22109 {
22110 addenemy(dngn_enemy_x[i],96,tmpscr->enemy[i],-14-i);
22111 }
22112 }
22113 }
22114 else
22115 {
22116
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 for(int32_t i=0; i<4; i++)
22117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 addenemy(dngn_enemy_x[i],96,tmpscr->enemy[i]?tmpscr->enemy[i]:(int32_t)eKEESE1,-14-i);
22118 }
22119 2 return;
22120 }
22121
22122 // check if it's been long enough to reload all enemies
22123
22124 150 int32_t loadcnt = 10;
22125 150 int16_t s = (currmap<<7)+currscr;
22126 150 bool beenhere = false;
22127 150 bool reload = true;
22128 150 bool unbeatablereload = true;
22129
22130
2/2
✓ Branch 0 taken 900 times.
✓ Branch 1 taken 150 times.
1050 for(int32_t i=0; i<6; i++)
22131
2/2
✓ Branch 0 taken 859 times.
✓ Branch 1 taken 41 times.
941 if(visited[i]==s)
22132 41 beenhere = true;
22133
22134
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 109 times.
150 if(!beenhere) //Okay so this basically checks the last 6 unique screen's you've been in and checks if the current screen is one of them.
22135 {
22136 109 visited[vhead]=s; //If not, it adds it to the array,
22137 109 vhead = (vhead+1)%6; //which overrides one of the others, and then moves onto the next.
22138 109 }
22139
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 36 times.
41 else if(game->guys[s]==0) //Then, if you have been here, and the number of enemies left on the screen is 0,
22140 {
22141 36 loadcnt = 0; //It will tell it not to load any enemies,
22142 36 reload = false; //both by setting loadcnt to 0 and making the reload if statement not run.
22143 36 }
22144
22145
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 114 times.
150 if(reload) //This if statement is only false if this screen is one of the last 6 screens you visited and you left 0 enemies alive.
22146 {
22147 114 loadcnt = game->guys[s]; //Otherwise, if this if statement is true, it will try to load the last amount of enemies you left alive.
22148
22149
2/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 108 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
114 if(loadcnt==0 || //Then, if the number of enemies is 0, that means you left 0 enemies alive on a screen but haven't been there in the past 6 screens.
22150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 (get_bit(quest_rules, qr_NO_LEAVE_ONE_ENEMY_ALIVE_TRICK) && !beenhere)) //Alternatively, if you have the quest rule enabled that always respawns all enemies after a period of time, and you haven't been here in 6 screens.
22151 108 loadcnt = 10; //That means all enemies need to be respawned.
22152
3/4
✓ Branch 0 taken 109 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 109 times.
✗ Branch 3 not taken.
114 if (!beenhere && get_bit(quest_rules, qr_UNBEATABLES_DONT_KEEP_DEAD))
22153 {
22154 for(int32_t i = 0; i<loadcnt && tmpscr->enemy[i]>0; i++)
22155 {
22156 if (!(guysbuf[tmpscr->enemy[i]].flags & guy_doesntcount))
22157 {
22158 unbeatablereload = false;
22159 }
22160 }
22161 if (unbeatablereload)
22162 {
22163 loadcnt = 10;
22164 }
22165 }
22166 114 }
22167
22168
3/4
✓ Branch 0 taken 150 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 149 times.
150 if((get_bit(quest_rules,qr_ALWAYSRET)) || (tmpscr->flags3&fENEMIESRETURN)) //If enemies always return is enabled quest-wide or for this screen,
22169 1 loadcnt = 10; //All enemies also need to be respawned.
22170
22171 150 int32_t pos=zc_oldrand()%9; //This sets up a variable for spawnEnemy to edit so as to spawn the enemies pseudo-randomly.
22172 150 int32_t clk=-15,x=0,y=0,fastguys=0; //clk being negative means the enemy is in it's spawn poof.
22173 150 int32_t i=0,guycnt=0; //Lastly, resets guycnt to 0 so spawnEnemy can increment it manually per-enemy.
22174
22175
4/4
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 458 times.
✓ Branch 2 taken 353 times.
✓ Branch 3 taken 150 times.
503 for(; i<loadcnt && tmpscr->enemy[i]>0; i++)
22176 {
22177 353 spawnEnemy(pos, clk, x, y, fastguys, i, guycnt, loadcnt);
22178
22179 353 --clk; //Each additional enemy spawns with a slightly longer spawn poof than the previous.
22180 353 }
22181
22182 150 game->guys[s] = guycnt;
22183 //} //if(true)
22184 80023 }
22185 3 void moneysign()
22186 {
22187 3 additem(48,108,iRupy,ipDUMMY);
22188 // textout(scrollbuf,zfont,"X",64,112,CSET(0)+1);
22189 3 set_clip_state(pricesdisplaybuf, 0);
22190 3 textout_ex(pricesdisplaybuf,zfont,"X",64,112,CSET(0)+1,-1);
22191 3 }
22192
22193 16 void putprices(bool sign)
22194 {
22195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if(fadeclk > 0) return;
22196 // refresh what's under the prices
22197 // for(int32_t i=5; i<12; i++)
22198 // putcombo(scrollbuf,i<<4,112,tmpscr->data[112+i],tmpscr->cpage);
22199
22200 16 rectfill(pricesdisplaybuf, 72, 112, pricesdisplaybuf->w-1, pricesdisplaybuf->h-1, 0);
22201 16 int32_t step=32;
22202 16 int32_t x=80;
22203
22204
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 10 times.
16 if(prices[2]==0)
22205 {
22206 10 step<<=1;
22207
22208
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if(prices[1]==0)
22209 {
22210 10 x=112;
22211 10 }
22212 10 }
22213
22214
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 48 times.
64 for(int32_t i=0; i<3; i++)
22215 {
22216 // Kind of stupid, but it works: 100000 is used to indicate that an item
22217 // has a price of zero rather than there being no item.
22218 // 100000 isn't a valid price, so this doesn't cause problems.
22219
3/4
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
48 if(prices[i]!=0 && prices[i]<100000)
22220 {
22221 char buf[8];
22222 18 sprintf(buf,sign?"%+3d":"%3d",prices[i]);
22223
22224 18 int32_t l=(int32_t)strlen(buf);
22225 18 set_clip_state(pricesdisplaybuf, 0);
22226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 textout_ex(pricesdisplaybuf,zfont,buf,x-(l>3?(l-3)<<3:0),112,CSET(0)+1,-1);
22227 18 }
22228
22229 48 x+=step;
22230 48 }
22231 16 }
22232
22233 // Setting up special rooms
22234 // Also called when the Letter is used successfully.
22235 13 void setupscreen()
22236 {
22237 13 boughtsomething=false;
22238 13 int32_t t=currscr<128?0:1;
22239 13 word str=tmpscr[t].str;
22240
22241 // Prices are already set to 0 in dowarp()
22242
3/15
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
13 switch(tmpscr[t].room)
22243 {
22244 case rSP_ITEM: // special item
22245 7 additem(120,89,tmpscr[t].catchall,ipONETIME2+ipHOLDUP+ipCHECK | ((tmpscr->flags8&fITEMSECRET) ? ipSECRETS : 0));
22246 7 break;
22247
22248 case rINFO: // pay for info
22249 {
22250 int32_t count = 0;
22251 int32_t base = 88;
22252 int32_t step = 5;
22253
22254 moneysign();
22255
22256 for(int32_t i=0; i<3; i++)
22257 {
22258 if(QMisc.info[tmpscr[t].catchall].str[i])
22259 {
22260 ++count;
22261 }
22262 else
22263 break;
22264 }
22265
22266 if(count)
22267 {
22268 if(count==1)
22269 {
22270 base = 88+32;
22271 }
22272
22273 if(count==2)
22274 {
22275 step = 6;
22276 }
22277
22278 for(int32_t i=0; i < count; i++)
22279 {
22280 additem((i << step)+base, 89, iRupy, ipMONEY + ipDUMMY);
22281 ((item*)items.spr(items.Count()-1))->PriceIndex = i;
22282 prices[i] = -(QMisc.info[tmpscr[t].catchall].price[i]);
22283 if(prices[i]==0)
22284 prices[i]=100000; // So putprices() knows there's an item here and positions the price correctly
22285 int32_t itemid = current_item_id(itype_wealthmedal);
22286
22287 if(itemid>=0 && prices[i]!=100000)
22288 {
22289 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22290 prices[i]=((prices[i]*itemsbuf[itemid].misc1)/100);
22291 else
22292 prices[i]-=itemsbuf[itemid].misc1;
22293 prices[i]=vbound(prices[i], -99999, 0);
22294 if(prices[i]==0)
22295 prices[i]=100000;
22296 }
22297
22298 if((QMisc.info[tmpscr[t].catchall].price[i])>1 && prices[i]>-1 && prices[i]!=100000)
22299 prices[i]=-1;
22300 }
22301 }
22302
22303 break;
22304 }
22305
22306 case rMONEY: // secret money
22307 additem(120,89,iRupy,ipONETIME+ipDUMMY+ipMONEY);
22308 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22309 break;
22310
22311 case rGAMBLE: // gambling
22312 prices[0]=prices[1]=prices[2]=-10;
22313 moneysign();
22314 additem(88,89,iRupy,ipMONEY+ipDUMMY);
22315 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22316 additem(120,89,iRupy,ipMONEY+ipDUMMY);
22317 ((item*)items.spr(items.Count()-1))->PriceIndex = 1;
22318 additem(152,89,iRupy,ipMONEY+ipDUMMY);
22319 ((item*)items.spr(items.Count()-1))->PriceIndex = 2;
22320 break;
22321
22322 case rREPAIR: // door repair
22323 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
22324 // }
22325 repaircharge=tmpscr[t].catchall;
22326 break;
22327
22328 case rMUPGRADE: // upgrade magic
22329 adjustmagic=true;
22330 break;
22331
22332 case rLEARNSLASH: // learn slash attack
22333 learnslash=true;
22334 break;
22335
22336 case rRP_HC: // heart container or red potion
22337 additem(88,89,iRPotion,ipONETIME2+ipHOLDUP+ipFADE);
22338 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22339 additem(152,89,iHeartC,ipONETIME2+ipHOLDUP+ipFADE);
22340 ((item*)items.spr(items.Count()-1))->PriceIndex = 1;
22341 break;
22342
22343 case rP_SHOP: // potion shop
22344 if(current_item(itype_letter)<i_letter_used)
22345 {
22346 str=0;
22347 break;
22348 }
22349
22350 [[fallthrough]];
22351 case rTAKEONE: // take one
22352 case rSHOP: // shop
22353 {
22354 3 int32_t count = 0;
22355 3 int32_t base = 88;
22356 3 int32_t step = 5;
22357
22358
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(tmpscr[t].room != rTAKEONE)
22359 3 moneysign();
22360
22361 //count and align the stuff
22362
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
12 for(int32_t i=0; i<3; ++i)
22363 {
22364
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(QMisc.shop[tmpscr[t].catchall].hasitem[count] != 0)
22365 {
22366 9 ++count;
22367 9 }
22368 else
22369 {
22370 break;
22371 }
22372 9 }
22373
22374
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(count==1)
22375 {
22376 base = 88+32;
22377 }
22378
22379
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(count==2)
22380 {
22381 step = 6;
22382 }
22383
22384
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 for(int32_t i=0; i<count; i++)
22385 {
22386 9 additem((i<<step)+base, 89, QMisc.shop[tmpscr[t].catchall].item[i], ipHOLDUP+ipFADE+(tmpscr[t].room == rTAKEONE ? ipONETIME2 : ipCHECK));
22387 9 ((item*)items.spr(items.Count()-1))->PriceIndex = i;
22388
22389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if(tmpscr[t].room != rTAKEONE)
22390 {
22391 9 prices[i] = QMisc.shop[tmpscr[t].catchall].price[i];
22392
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if(prices[i]==0)
22393 prices[i]=100000; // So putprices() knows there's an item here and positions the price correctly
22394 9 int32_t itemid = current_item_id(itype_wealthmedal);
22395
22396
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9 if(itemid>=0 && prices[i]!=100000)
22397 {
22398 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22399 prices[i]=((prices[i]*itemsbuf[itemid].misc1)/100);
22400 else
22401 prices[i]+=itemsbuf[itemid].misc1;
22402 prices[i]=vbound(prices[i], 0, 99999);
22403 if(prices[i]==0)
22404 prices[i]=100000;
22405 }
22406
22407
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 if((QMisc.shop[tmpscr[t].catchall].price[i])>1 && prices[i]<1)
22408 prices[i]=1;
22409 9 }
22410 9 }
22411
22412 3 break;
22413 }
22414 case rBOTTLESHOP: // bottle shop
22415 {
22416 int32_t count = 0;
22417 int32_t base = 88;
22418 int32_t step = 5;
22419
22420 moneysign();
22421 bottleshoptype const& bst = QMisc.bottle_shop_types[tmpscr[t].catchall];
22422 //count and align the stuff
22423 for(int32_t i=0; i<3; ++i)
22424 {
22425 if(bst.fill[count] != 0)
22426 {
22427 ++count;
22428 }
22429 else
22430 {
22431 break;
22432 }
22433 }
22434
22435 if(count==1)
22436 {
22437 base = 88+32;
22438 }
22439
22440 if(count==2)
22441 {
22442 step = 6;
22443 }
22444
22445 for(int32_t i=0; i<count; i++)
22446 {
22447 adddummyitem((i<<step)+base, 89, /*Use item 0 as a dummy...*/0, ipHOLDUP+ipFADE+ipCHECK);
22448 //{ Setup dummy item
22449 item* curItem = ((item*)items.spr(items.Count()-1));
22450 curItem->PriceIndex = i;
22451 newcombo const& cmb = combobuf[bst.comb[i]];
22452 curItem->o_tile = cmb.o_tile;
22453 curItem->o_cset = bst.cset[i];
22454 curItem->cs = curItem->o_cset;
22455 curItem->tile = cmb.o_tile;
22456 curItem->o_speed = cmb.speed;
22457 curItem->o_delay = 0;
22458 curItem->frames = cmb.frames;
22459 curItem->flip = cmb.flip;
22460 curItem->family = itype_bottlefill; //no pickup w/o empty bottle
22461 curItem->pstring = 0;
22462 curItem->pickup = ipHOLDUP+ipFADE+ipCHECK;
22463 curItem->flash = false;
22464 curItem->twohand = false;
22465 curItem->anim = true;
22466 curItem->hxsz=1;
22467 curItem->hyofs=4;
22468 curItem->hysz=12;
22469 curItem->script=0;
22470 curItem->txsz=1;
22471 curItem->tysz=1;
22472 //}
22473
22474 prices[i] = bst.price[i];
22475 if(prices[i]==0)
22476 prices[i]=100000; // So putprices() knows there's an item here and positions the price correctly
22477 int32_t itemid = current_item_id(itype_wealthmedal);
22478
22479 if(itemid>=0 && prices[i]!=100000)
22480 {
22481 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22482 prices[i]=((prices[i]*itemsbuf[itemid].misc1)/100);
22483 else
22484 prices[i]+=itemsbuf[itemid].misc1;
22485 prices[i]=vbound(prices[i], 0, 99999);
22486 if(prices[i]==0)
22487 prices[i]=100000;
22488 }
22489
22490 if((bst.price[i])>1 && prices[i]<1)
22491 prices[i]=1;
22492 }
22493
22494 break;
22495 }
22496
22497 case rBOMBS: // more bombs
22498 additem(120,89,iRupy,ipDUMMY+ipMONEY);
22499 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22500 prices[0]=-tmpscr[t].catchall;
22501 break;
22502
22503 case rARROWS: // more arrows
22504 additem(120,89,iRupy,ipDUMMY+ipMONEY);
22505 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22506 prices[0]=-tmpscr[t].catchall;
22507 break;
22508
22509 case rSWINDLE: // leave heart container or money
22510 additem(88,89,iHeartC,ipDUMMY+ipMONEY);
22511 ((item*)items.spr(items.Count()-1))->PriceIndex = 0;
22512 prices[0]=-1;
22513 additem(152,89,iRupy,ipDUMMY+ipMONEY);
22514 ((item*)items.spr(items.Count()-1))->PriceIndex = 1;
22515 prices[1]=-tmpscr[t].catchall;
22516 break;
22517
22518 }
22519
22520
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
13 if(tmpscr[t].room == rBOMBS || tmpscr[t].room == rARROWS)
22521 {
22522 int32_t i = (tmpscr[t].room == rSWINDLE ? 1 : 0);
22523 int32_t itemid = current_item_id(itype_wealthmedal);
22524
22525 if(itemid >= 0)
22526 {
22527 if(itemsbuf[itemid].flags & ITEM_FLAG1)
22528 prices[i]*=(itemsbuf[itemid].misc1/100.0);
22529 else
22530 prices[i]+=itemsbuf[itemid].misc1;
22531 }
22532
22533 if(tmpscr[t].catchall>1 && prices[i]>-1)
22534 prices[i]=-1;
22535 }
22536
22537 13 putprices(false);
22538
22539
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 if(str)
22540 {
22541 13 donewmsg(str);
22542 13 }
22543 else
22544 {
22545 Hero.unfreeze();
22546 }
22547 13 }
22548
22549 // Increments msgptr and returns the control code argument pointed at.
22550 word grab_next_argument()
22551 {
22552 if(unsigned(msgptr+1)>=MsgStrings[msgstr].s.size()) return 0;
22553 byte val=MsgStrings[msgstr].s[++msgptr]-1;
22554 word ret=val;
22555
22556 // If an argument is succeeded by 255, then it's a three-byte argument -
22557 // between 254 and 65535 (or whatever the maximum actually is)
22558 if((unsigned(msgptr+2)<MsgStrings[msgstr].s.size())
22559 && uint8_t(MsgStrings[msgstr].s[msgptr+1]) == 255)
22560 {
22561 val=MsgStrings[msgstr].s[msgptr+2];
22562 word next=val;
22563 ret += 254*next;
22564 msgptr+=2;
22565 }
22566
22567 return ret;
22568 }
22569
22570 enum
22571 {
22572 MNU_CURSOR_TILE, MNU_CURSOR_CSET,
22573 MNU_CURSOR_WID, MNU_CURSOR_HEI, MNU_CURSOR_FLIP,
22574
22575 MNU_CHOSEN, MNU_TIMER, MNU_CAN_CONFIRM,
22576
22577 MNU_DATA_MAX
22578 };
22579 struct menu_choice
22580 {
22581 int32_t x, y;
22582 int32_t pos;
22583 int32_t upos, dpos, lpos, rpos;
22584 menu_choice() : x(0), y(0), pos(0), upos(0), dpos(0), lpos(0), rpos(0)
22585 {}
22586 menu_choice(int32_t x, int32_t y, int32_t pos, int32_t upos,
22587 int32_t dpos, int32_t lpos, int32_t rpos)
22588 : x(x), y(y), pos(pos), upos(upos), dpos(dpos), lpos(lpos), rpos(rpos)
22589 {}
22590 };
22591 static int32_t msg_menu_data[MNU_DATA_MAX];
22592 static bool do_run_menu = false;
22593 bool do_end_str = false;
22594 static bool wait_advance = false;
22595 14 static std::map<int32_t, menu_choice> menu_options;
22596 205 void clr_msg_data()
22597 {
22598 205 do_end_str = false;
22599 205 wait_advance = false;
22600 205 do_run_menu = false;
22601 205 menu_options.clear();
22602 205 memset(msg_menu_data, 0, sizeof(msg_menu_data));
22603 205 }
22604
22605 static bool doing_name_insert = false;
22606 static char namebuf[9] = {0};
22607 static char* nameptr = NULL;
22608 static int32_t ssc_tile_hei = -1, ssc_tile_hei_buf = -1;
22609 bool runMenuCursor()
22610 {
22611 clear_bitmap(msg_menu_bmp_buf);
22612 if(!menu_options.size())
22613 {
22614 msg_menu_data[MNU_CHOSEN] = 0;
22615 return true; //end menu
22616 }
22617 int32_t pos = msg_menu_data[MNU_CHOSEN];
22618 //If the cursor is at an invalid pos, find the first pos >= 0...
22619 if(menu_options.find(pos) == menu_options.end())
22620 {
22621 pos = 0;
22622 while(menu_options.find(pos) == menu_options.end())
22623 ++pos;
22624 }
22625 menu_choice* ch = &menu_options[pos];
22626
22627 bool pressed = true;
22628 if(rUp()) pos = ch->upos;
22629 else if(rDown()) pos = ch->dpos;
22630 else if(rLeft()) pos = ch->lpos;
22631 else if(rRight()) pos = ch->rpos;
22632 else pressed = false;
22633
22634 if(pressed)
22635 msg_menu_data[MNU_TIMER] = 1;
22636
22637 bool hold_input = !((msg_menu_data[MNU_TIMER]++) % 5);
22638 bool held = false;
22639 if(hold_input)
22640 {
22641 held = true;
22642 if(Up()) pos = ch->upos;
22643 else if(Down()) pos = ch->dpos;
22644 else if(Left()) pos = ch->lpos;
22645 else if(Right()) pos = ch->rpos;
22646 else held = false;
22647 }
22648 //If the cursor is at an invalid pos, find the first pos >= 0...
22649 if(menu_options.find(pos) == menu_options.end())
22650 {
22651 pos = 0;
22652 while(menu_options.find(pos) == menu_options.end())
22653 ++pos;
22654 }
22655 if((pressed || held) && pos != msg_menu_data[MNU_CHOSEN])
22656 sfx(MsgStrings[msgstr].sfx);
22657
22658 ch = &menu_options[pos];
22659 overtileblock16(msg_menu_bmp_buf, msg_menu_data[MNU_CURSOR_TILE],
22660 ch->x, ch->y, (int32_t)ceil(msg_menu_data[MNU_CURSOR_WID]/16.0),
22661 (int32_t)ceil(msg_menu_data[MNU_CURSOR_HEI]/16.0),
22662 msg_menu_data[MNU_CURSOR_CSET], msg_menu_data[MNU_CURSOR_FLIP]);
22663
22664 msg_menu_data[MNU_CHOSEN] = pos;
22665
22666 if(!msg_menu_data[MNU_CAN_CONFIRM]) //Prevent instantly accepting when holding A
22667 {
22668 rAbtn(); //Eat
22669 if(!cAbtn()) msg_menu_data[MNU_CAN_CONFIRM] = 1;
22670 }
22671
22672 bool ret = (pressed || held) ? false : rAbtn();
22673 //Eat inputs
22674 rUp(); rDown(); rLeft(); rRight(); rAbtn();
22675
22676 if(ret)
22677 menu_options.clear();
22678
22679 return ret;
22680 //false if pos changed this frame; no confirming while moving the cursor!
22681 }
22682
22683 3504 bool bottom_margin_clip()
22684 {
22685 3804 return !get_bit(quest_rules, qr_OLD_STRING_EDITOR_MARGINS)
22686
2/2
✓ Branch 0 taken 300 times.
✓ Branch 1 taken 3204 times.
3504 && cursor_y >= (msg_h + (get_bit(quest_rules,qr_STRING_FRAME_OLD_WIDTH_HEIGHT)?16:0) - msg_margins[down]);
22687 }
22688
22689 700 bool parsemsgcode()
22690 {
22691
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 683 times.
700 if(msgptr>=MsgStrings[msgstr].s.size()) return false;
22692 683 byte c = byte(MsgStrings[msgstr].s[msgptr]-1);
22693
1/36
✗ Branch 0 not taken.
✓ Branch 1 taken 683 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
683 switch(c)
22694 {
22695 case MSGC_NEWLINE:
22696 {
22697 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
22698 ssc_tile_hei = ssc_tile_hei_buf;
22699 ssc_tile_hei_buf = -1;
22700 cursor_y += thei + MsgStrings[msgstr].vspace;
22701 cursor_x=msg_margins[left];
22702 return true;
22703 }
22704
22705 case MSGC_COLOUR:
22706 {
22707 int32_t cset = (grab_next_argument());
22708 msgcolour = CSET(cset)+(grab_next_argument());
22709 return true;
22710 }
22711
22712 case MSGC_SHDCOLOR:
22713 {
22714 int32_t cset = (grab_next_argument());
22715 msg_shdcol = CSET(cset)+(grab_next_argument());
22716 return true;
22717 }
22718 case MSGC_SHDTYPE:
22719 {
22720 msg_shdtype = grab_next_argument();
22721 return true;
22722 }
22723
22724 case MSGC_SPEED:
22725 {
22726 msgspeed=grab_next_argument();
22727 return true;
22728 }
22729
22730 case MSGC_CTRUP:
22731 {
22732 int32_t a1 = grab_next_argument();
22733 int32_t a2 = grab_next_argument();
22734 game->change_counter(a2, a1);
22735 return true;
22736 }
22737
22738 case MSGC_CTRDN:
22739 {
22740 int32_t a1 = grab_next_argument();
22741 int32_t a2 = grab_next_argument();
22742 game->change_counter(-a2, a1);
22743 return true;
22744 }
22745
22746 case MSGC_CTRSET:
22747 {
22748 int32_t a1 = grab_next_argument();
22749 int32_t a2 = grab_next_argument();
22750 game->set_counter(vbound(a2, 0, game->get_maxcounter(a1)), a1);
22751 return true;
22752 }
22753
22754 case MSGC_CTRUPPC:
22755 case MSGC_CTRDNPC:
22756 case MSGC_CTRSETPC:
22757 {
22758 int32_t code = MsgStrings[msgstr].s[msgptr]-1;
22759 int32_t counter = grab_next_argument();
22760 int32_t amount = grab_next_argument();
22761 amount = int32_t(vbound(amount*0.01, 0.0, 1.0)*game->get_maxcounter(counter));
22762
22763 if(code==MSGC_CTRDNPC)
22764 amount*=-1;
22765
22766 if(code==MSGC_CTRSETPC)
22767 game->set_counter(amount, counter);
22768 else
22769 game->change_counter(amount, counter);
22770
22771 return true;
22772 }
22773
22774 case MSGC_GIVEITEM:
22775 {
22776 int32_t itemID = grab_next_argument();
22777
22778 getitem(itemID, true);
22779 if ( !item_doscript[itemID] && (((unsigned)itemID) < 256) )
22780 {
22781 itemScriptData[itemID].Clear();
22782 memset(item_stack[itemID], 0xFFFF, MAX_SCRIPT_REGISTERS * sizeof(int32_t));
22783 if ( (itemsbuf[itemID].flags&ITEM_PASSIVESCRIPT) ) item_doscript[itemID] = 1;
22784 }
22785 return true;
22786 }
22787
22788
22789 case MSGC_WARP:
22790 {
22791 int32_t dmap = grab_next_argument();
22792 int32_t scrn = grab_next_argument();
22793 int32_t dx = grab_next_argument();
22794 int32_t dy = grab_next_argument();
22795 int32_t wfx = grab_next_argument();
22796 int32_t sfx = grab_next_argument();
22797 if(dx >= MAX_SCC_ARG) dx = -1;
22798 if(dy >= MAX_SCC_ARG) dy = -1;
22799 FFCore.warp_player(wtIWARP, dmap, scrn, dx, dy, wfx, sfx, warpFlagDONTKILLMUSIC, 0);
22800 return true;
22801 }
22802
22803 case MSGC_SETSCREEND:
22804 {
22805 int32_t dmap = (grab_next_argument()<<7); //dmap and screen may be transposed here.
22806 int32_t screen = grab_next_argument();
22807 int32_t reg = grab_next_argument();
22808 int32_t val = grab_next_argument();
22809 FFCore.set_screen_d(screen + dmap, reg, val);
22810 return true;
22811 }
22812 case MSGC_TAKEITEM:
22813 {
22814 int32_t itemID = grab_next_argument();
22815 if ( item_doscript[itemID] )
22816 {
22817 item_doscript[itemID] = 4; //Val of 4 means 'clear stack and quit'
22818 }
22819 takeitem(itemID);
22820 if ( game->forced_bwpn == itemID )
22821 {
22822 game->forced_bwpn = -1;
22823 } //not else if! -Z
22824 if ( game->forced_awpn == itemID )
22825 {
22826 game->forced_awpn = -1;
22827 }
22828 if ( game->forced_xwpn == itemID )
22829 {
22830 game->forced_xwpn = -1;
22831 } //not else if! -Z
22832 if ( game->forced_ywpn == itemID )
22833 {
22834 game->forced_ywpn = -1;
22835 }
22836 verifyBothWeapons();
22837 return true;
22838 }
22839
22840 case MSGC_SFX:
22841 {
22842 sfx((int32_t)grab_next_argument(),128);
22843 return true;
22844 }
22845
22846 case MSGC_MIDI:
22847 {
22848 int32_t music = (int32_t)(grab_next_argument());
22849
22850 if(music==0)
22851 music_stop();
22852 else
22853 jukebox(music+(ZC_MIDI_COUNT-1));
22854
22855 return true;
22856 }
22857
22858 case MSGC_NAME:
22859 {
22860 doing_name_insert = true;
22861 sprintf(namebuf, "%s", game->get_name());
22862 nameptr = namebuf;
22863 return true;
22864 }
22865
22866 case MSGC_DRAWTILE:
22867 {
22868 int32_t tl = grab_next_argument();
22869 int32_t cs = grab_next_argument();
22870 int32_t t_wid = grab_next_argument();
22871 int32_t t_hei = grab_next_argument();
22872 int32_t fl = grab_next_argument();
22873
22874 if(cursor_x+MsgStrings[msgstr].hspace + t_wid > msg_w-msg_margins[right])
22875 {
22876 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
22877 ssc_tile_hei = ssc_tile_hei_buf;
22878 ssc_tile_hei_buf = -1;
22879 cursor_y += thei + MsgStrings[msgstr].vspace;
22880 if(bottom_margin_clip()) return true;
22881 cursor_x=msg_margins[left];
22882 }
22883
22884 overtileblock16(msg_txt_bmp_buf, tl, cursor_x, cursor_y, (int32_t)ceil(t_wid/16.0), (int32_t)ceil(t_hei/16.0), cs, fl);
22885 ssc_tile_hei_buf = zc_max(ssc_tile_hei_buf, t_hei);
22886 cursor_x += MsgStrings[msgstr].hspace + t_wid;
22887 return true;
22888 }
22889
22890 case MSGC_GOTOIFRAND:
22891 {
22892 int32_t odds = (int32_t)(grab_next_argument());
22893
22894 if(!odds || !(zc_oldrand()%odds))
22895 goto switched;
22896
22897 (void)grab_next_argument();
22898 return true;
22899 }
22900
22901 case MSGC_GOTOIFGLOBAL:
22902 {
22903 int32_t arg = (int32_t)grab_next_argument();
22904 int32_t d = zc_min(7,arg);
22905 int32_t s = ((get_currdmap())<<7) + get_currscr()-(DMaps[get_currdmap()].type==dmOVERW ? 0 : DMaps[get_currdmap()].xoff);
22906 arg = (int32_t)grab_next_argument();
22907
22908 if(game->screen_d[s][d] >= arg)
22909 goto switched;
22910
22911 (void)grab_next_argument();
22912 return true;
22913 }
22914
22915 case MSGC_CHANGEPORTRAIT:
22916 {
22917 return true; //not implemented
22918 }
22919
22920 case MSGC_GOTOIFCREEND:
22921 {
22922 int32_t dmap = (grab_next_argument()<<7); //dmap and screen may be transposed here.
22923 int32_t screen = grab_next_argument();
22924 int32_t reg = grab_next_argument();
22925 int32_t val = grab_next_argument();
22926 //int32_t nxtstr = grab_next_argument();
22927 if ( FFCore.get_screen_d(screen + dmap, reg) >= val )
22928 {
22929 goto switched;
22930 }
22931 (void)grab_next_argument();
22932 return true;
22933 }
22934
22935 case MSGC_GOTOIF:
22936 {
22937 int32_t it = (int32_t)grab_next_argument();
22938
22939 if(unsigned(it)<MAXITEMS && game->item[it])
22940 goto switched;
22941
22942 (void)grab_next_argument();
22943 return true;
22944 }
22945
22946 case MSGC_GOTOIFCTR:
22947 {
22948 if(game->get_counter(grab_next_argument())>=grab_next_argument())
22949 goto switched;
22950
22951 (void)grab_next_argument();
22952 return true;
22953 }
22954
22955 case MSGC_GOTOIFCTRPC:
22956 {
22957 int32_t counter = grab_next_argument();
22958 int32_t amount = (int32_t)(((grab_next_argument())/100)*game->get_maxcounter(counter));
22959
22960 if(game->get_counter(counter)>=amount)
22961 goto switched;
22962
22963 (void)grab_next_argument();
22964 return true;
22965 }
22966
22967 case MSGC_GOTOIFTRICOUNT:
22968 {
22969 if(TriforceCount() >= (int32_t)(grab_next_argument()))
22970 goto switched;
22971
22972 (void)grab_next_argument();
22973 return true;
22974 }
22975
22976 case MSGC_GOTOIFTRI:
22977 {
22978 int32_t lev = (int32_t)(grab_next_argument());
22979
22980 if(lev<MAXLEVELS && game->lvlitems[lev]&liTRIFORCE)
22981 goto switched;
22982
22983 (void)grab_next_argument();
22984 return true;
22985 }
22986
22987 case MSGC_SETUPMENU:
22988 {
22989 msg_menu_data[MNU_CURSOR_TILE] = grab_next_argument();
22990 msg_menu_data[MNU_CURSOR_CSET] = grab_next_argument();
22991 msg_menu_data[MNU_CURSOR_WID] = grab_next_argument();
22992 msg_menu_data[MNU_CURSOR_HEI] = grab_next_argument();
22993 msg_menu_data[MNU_CURSOR_FLIP] = grab_next_argument();
22994 return true;
22995 }
22996
22997 case MSGC_MENUCHOICE:
22998 {
22999 int32_t pos = grab_next_argument();
23000 int32_t upos = grab_next_argument();
23001 int32_t dpos = grab_next_argument();
23002 int32_t lpos = grab_next_argument();
23003 int32_t rpos = grab_next_argument();
23004 if(cursor_x+MsgStrings[msgstr].hspace + msg_menu_data[MNU_CURSOR_WID] > msg_w-msg_margins[right])
23005 {
23006 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23007 ssc_tile_hei = ssc_tile_hei_buf;
23008 ssc_tile_hei_buf = -1;
23009 cursor_y += thei + MsgStrings[msgstr].vspace;
23010 if(bottom_margin_clip()) break;
23011 cursor_x=msg_margins[left];
23012 }
23013
23014 menu_options[pos] = menu_choice(cursor_x, cursor_y, pos,
23015 upos, dpos, lpos, rpos);
23016
23017 ssc_tile_hei_buf = zc_max(ssc_tile_hei_buf, msg_menu_data[MNU_CURSOR_HEI]);
23018 cursor_x += MsgStrings[msgstr].hspace + msg_menu_data[MNU_CURSOR_WID];
23019 return true;
23020 }
23021
23022 case MSGC_RUNMENU:
23023 {
23024 msg_menu_data[MNU_CHOSEN] = 0;
23025 msg_menu_data[MNU_CAN_CONFIRM] = 0;
23026 if(menu_options.size() < 1)
23027 return true;
23028 do_run_menu = true;
23029 return true;
23030 }
23031
23032 case MSGC_GOTOMENUCHOICE:
23033 {
23034 int32_t choice = grab_next_argument();
23035 if(msg_menu_data[MNU_CHOSEN] == choice)
23036 goto switched;
23037 (void)grab_next_argument();
23038 return true;
23039 }
23040
23041 case MSGC_ENDSTRING:
23042 {
23043 do_end_str = true;
23044 return true;
23045 }
23046 case MSGC_WAIT_ADVANCE:
23047 {
23048 wait_advance = true;
23049 linkedmsgclk = 51;
23050 return true;
23051 }
23052 case MSGC_TRIGSECRETS:
23053 {
23054 bool perm = (bool)grab_next_argument();
23055 hidden_entrance(0, true, false, -8);
23056 if(perm)
23057 setmapflag(mSECRET);
23058 return true;
23059 }
23060 case MSGC_SETSCREENSTATE:
23061 {
23062 int32_t flag = int32_t(grab_next_argument());
23063 if(unsigned(flag)>=mMAXIND)
23064 {
23065 Z_error("SCC 133: Flag %d is invalid\n", flag);
23066 return true;
23067 }
23068 bool state = bool(grab_next_argument());
23069 if(state)
23070 setmapflag(1<<flag);
23071 else
23072 unsetmapflag(1<<flag,true);
23073 return true;
23074 }
23075 case MSGC_SETSCREENSTATER:
23076 {
23077 int32_t map = (int32_t)grab_next_argument();
23078 int32_t scrid = (int32_t)grab_next_argument();
23079 if(map < 1 || map > map_count)
23080 {
23081 Z_error("SCC 134: Map %d is invalid\n", map);
23082 return true;
23083 }
23084 if(unsigned(scrid)>=0x80)
23085 {
23086 Z_error("SCC 134: Screen %d is invalid\n", scrid);
23087 return true;
23088 }
23089
23090 int32_t flag = int32_t(grab_next_argument());
23091 if(unsigned(flag)>=mMAXIND)
23092 {
23093 Z_error("SCC 134: Flag %d is invalid\n", flag);
23094 return true;
23095 }
23096 bool state = bool(grab_next_argument());
23097 if(state)
23098 setmapflag(mapind(map,scrid),1<<flag);
23099 else
23100 unsetmapflag(mapind(map,scrid),1<<flag,true);
23101 return true;
23102 }
23103 switched:
23104 int32_t lev = (int32_t)(grab_next_argument());
23105 if(lev && get_bit(quest_rules, qr_SCC_GOTO_RESPECTS_CONTFLAG)
23106 && (MsgStrings[lev].stringflags & STRINGFLAG_CONT))
23107 {
23108 msgstr=lev;
23109 msgpos=msgptr=0;
23110 msgfont=setmsgfont();
23111 }
23112 else donewmsg(lev);
23113 msgptr--; // To counteract it being incremented after this routine is called.
23114 putprices(false);
23115 return true;
23116 }
23117
23118 683 return false;
23119 700 }
23120
23121 // Wraps the message string... probably.
23122 683 void wrapmsgstr(char *s3)
23123 {
23124 683 int32_t j=0;
23125
23126
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 587 times.
683 if(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP)
23127 {
23128
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 76 times.
96 if(msgspace)
23129 {
23130 20 char c = MsgStrings[msgstr].s[msgptr];
23131
3/6
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
20 if(c != ' ' && c >= 32 && c <= 126)
23132 {
23133
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 20 times.
97 for(int32_t k=0; MsgStrings[msgstr].s[msgptr+k] && MsgStrings[msgstr].s[msgptr+k] != ' '; k++)
23134 {
23135
2/4
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 77 times.
77 if(MsgStrings[msgstr].s[msgptr+k] >= 32 && MsgStrings[msgstr].s[msgptr+k] <= 126) s3[j++] = MsgStrings[msgstr].s[msgptr+k];
23136 77 }
23137
23138 20 s3[j] = 0;
23139 20 msgspace = false;
23140 20 }
23141 else
23142 {
23143 s3[0] = c;
23144 s3[1] = 0;
23145 }
23146 20 }
23147 else
23148 {
23149 76 s3[0] = MsgStrings[msgstr].s[msgptr];
23150 76 s3[1] = 0;
23151
23152
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 19 times.
76 if(s3[0] == ' ') msgspace=true;
23153 }
23154 96 }
23155 else
23156 {
23157 587 s3[0] = MsgStrings[msgstr].s[msgptr];
23158 587 s3[1] = 0;
23159 }
23160 683 }
23161
23162 // Returns true if the pointer is at a string's
23163 // null terminator or a trailing space
23164 3293 bool atend(char const* str)
23165 {
23166 3293 int32_t i=0;
23167
23168
2/2
✓ Branch 0 taken 43930 times.
✓ Branch 1 taken 3293 times.
47223 while(str[i]==' ')
23169 43930 i++;
23170
23171 3293 return str[i]=='\0';
23172 }
23173
23174 77941 void putmsg()
23175 {
23176 77941 bool oldmargin = get_bit(quest_rules, qr_OLD_STRING_EDITOR_MARGINS)!=0;
23177
2/2
✓ Branch 0 taken 73594 times.
✓ Branch 1 taken 4347 times.
77941 if(!msgorig) msgorig=msgstr;
23178
23179
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 77941 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
77941 if(wait_advance && linkedmsgclk < 1)
23180 linkedmsgclk = 1;
23181
2/2
✓ Branch 0 taken 77544 times.
✓ Branch 1 taken 397 times.
77941 if(linkedmsgclk>0)
23182 {
23183
2/2
✓ Branch 0 taken 197 times.
✓ Branch 1 taken 200 times.
397 if(linkedmsgclk==1)
23184 {
23185
4/6
✓ Branch 0 taken 197 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 193 times.
197 if(do_end_str||cAbtn()||cBbtn())
23186 {
23187 4 do_end_str = false;
23188 4 linkedmsgclk = 0;
23189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(wait_advance)
23190 {
23191 wait_advance = false;
23192 }
23193 else
23194 {
23195 4 msgstr=MsgStrings[msgstr].nextstring;
23196
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
4 if(!msgstr && enqueued_str)
23197 {
23198 msgstr = enqueued_str;
23199 enqueued_str = 0;
23200 }
23201
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if(!msgstr)
23202 {
23203 1 msgfont=zfont;
23204
23205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(tmpscr->room!=rGRUMBLE)
23206 1 blockpath=false;
23207
23208 1 dismissmsg();
23209 1 goto disappear;
23210 }
23211
23212 3 donewmsg(msgstr);
23213 3 putprices(false);
23214 }
23215 3 }
23216 196 }
23217 else
23218 {
23219 200 --linkedmsgclk;
23220 }
23221 396 }
23222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77940 times.
77940 if(wait_advance) return; //Waiting for buttonpress
23223
23224
7/10
✓ Branch 0 taken 77940 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4332 times.
✓ Branch 3 taken 73608 times.
✓ Branch 4 taken 4332 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2093 times.
✓ Branch 7 taken 2239 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2093 times.
77940 if(!do_run_menu && (!msgstr || msgpos>=10000 || msgptr>=MsgStrings[msgstr].s.size() || bottom_margin_clip()))
23225 {
23226
2/2
✓ Branch 0 taken 2239 times.
✓ Branch 1 taken 73608 times.
75847 if(!msgstr)
23227 73608 msgorig=0;
23228
23229 75847 msg_active = false;
23230 75847 return;
23231 }
23232
23233 2093 msg_onscreen = true; // Now the message is onscreen (see donewmsg()).
23234
23235 char s3[145];
23236 int32_t tlength;
23237
23238 // Bypass the string with the B button!
23239
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2093 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2093 times.
2093 if(((cBbtn())&&(get_bit(quest_rules,qr_ALLOWMSGBYPASS))) || msgspeed==0)
23240 {
23241 //finish writing out the string
23242 while(msgptr<MsgStrings[msgstr].s.size() && !atend(MsgStrings[msgstr].s.c_str()+msgptr))
23243 {
23244 if(msgspeed && !(cBbtn() && get_bit(quest_rules,qr_ALLOWMSGBYPASS)))
23245 goto breakout; // break out if message speed was changed to non-zero
23246 else if(!do_run_menu && !doing_name_insert && !parsemsgcode())
23247 {
23248 if(bottom_margin_clip())
23249 break;
23250
23251 wrapmsgstr(s3);
23252
23253 if(MsgStrings[msgstr].s[msgptr]==' ')
23254 {
23255 tlength = msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]) + MsgStrings[msgstr].hspace;
23256
23257 if(cursor_x+tlength > (msg_w-msg_margins[right])
23258 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23259 ? true : strcmp(s3," ")!=0))
23260 {
23261 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23262 ssc_tile_hei = ssc_tile_hei_buf;
23263 ssc_tile_hei_buf = -1;
23264 cursor_y += thei + MsgStrings[msgstr].vspace;
23265 if(bottom_margin_clip()) break;
23266 cursor_x=msg_margins[left];
23267 }
23268
23269 char buf[2] = {0};
23270 sprintf(buf,"%c",MsgStrings[msgstr].s[msgptr]);
23271
23272 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23273
23274 cursor_x+=tlength;
23275 }
23276 else
23277 {
23278 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23279 if(cursor_x+tlength > (msg_w-msg_margins[right])
23280 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23281 ? true : strcmp(s3," ")!=0))
23282 {
23283 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23284 ssc_tile_hei = ssc_tile_hei_buf;
23285 ssc_tile_hei_buf = -1;
23286 cursor_y += thei + MsgStrings[msgstr].vspace;
23287 if(bottom_margin_clip()) break;
23288 cursor_x=msg_margins[left];
23289 }
23290
23291 sfx(MsgStrings[msgstr].sfx);
23292
23293 char buf[2] = {0};
23294 sprintf(buf,"%c",MsgStrings[msgstr].s[msgptr]);
23295
23296 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23297
23298 cursor_x += msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]);
23299 cursor_x += MsgStrings[msgstr].hspace;
23300 }
23301
23302 msgpos++;
23303 }
23304 if(do_run_menu)
23305 {
23306 if(runMenuCursor())
23307 {
23308 do_run_menu = false;
23309 }
23310 else break;
23311 }
23312 if(doing_name_insert)
23313 {
23314 if(*nameptr)
23315 {
23316 if(bottom_margin_clip())
23317 break;
23318
23319 char s3[9] = {0};
23320
23321 if(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP)
23322 {
23323 strcpy(s3, nameptr);
23324 }
23325 else
23326 {
23327 s3[0] = *nameptr;
23328 s3[1] = 0;
23329 }
23330
23331 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23332
23333 if(cursor_x+tlength > (msg_w-msg_margins[right])
23334 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23335 ? true : strcmp(s3," ")!=0))
23336 {
23337 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23338 ssc_tile_hei = ssc_tile_hei_buf;
23339 ssc_tile_hei_buf = -1;
23340 cursor_y += thei + MsgStrings[msgstr].vspace;
23341 if(bottom_margin_clip()) break;
23342 cursor_x=msg_margins[left];
23343 }
23344
23345 sfx(MsgStrings[msgstr].sfx);
23346
23347 char buf[2] = {0};
23348 sprintf(buf,"%c",*nameptr);
23349
23350 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23351
23352 cursor_x += msgfont->vtable->char_length(msgfont, *nameptr);
23353 cursor_x += MsgStrings[msgstr].hspace;
23354 ++nameptr;
23355 continue; //don't advance the msgptr, as the next char in it was not processed!
23356 }
23357 else doing_name_insert = false;
23358 }
23359 ++msgptr;
23360 if(do_end_str)
23361 goto strendcheck;
23362 if(wait_advance)
23363 return;
23364 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23365 {
23366 if(MsgStrings[msgstr].nextstring)
23367 {
23368 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23369 {
23370 msgstr=MsgStrings[msgstr].nextstring;
23371 msgpos=msgptr=0;
23372 msgfont=setmsgfont();
23373 }
23374 }
23375 }
23376 }
23377
23378 if (!do_run_menu)
23379 {
23380 msgclk = 72;
23381 msgpos = 10000;
23382 }
23383 }
23384 else
23385 2093 {
23386 breakout:
23387
23388
6/6
✓ Branch 0 taken 1713 times.
✓ Branch 1 taken 380 times.
✓ Branch 2 taken 735 times.
✓ Branch 3 taken 978 times.
✓ Branch 4 taken 303 times.
✓ Branch 5 taken 432 times.
2093 if(((msgclk++)%(msgspeed+1)<msgspeed)&&((!cAbtn())||(!get_bit(quest_rules,qr_ALLOWFASTMSG))))
23389 1410 return;
23390 }
23391
23392 // Start writing the string
23393
2/2
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 17 times.
700 if(msgptr == 0)
23394 {
23395
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 42 times.
59 while(MsgStrings[msgstr].s[msgptr]==' ')
23396 {
23397 42 tlength = msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]) + MsgStrings[msgstr].hspace;
23398
23399
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
42 if(cursor_x+tlength > (msg_w-msg_margins[right])
23400
1/6
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
42 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23401 ? 1 : strcmp(s3," ")!=0))
23402 {
23403 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23404 ssc_tile_hei = ssc_tile_hei_buf;
23405 ssc_tile_hei_buf = -1;
23406 cursor_y += thei + MsgStrings[msgstr].vspace;
23407 if(bottom_margin_clip()) break;
23408 cursor_x=msg_margins[left];
23409 }
23410
23411 42 cursor_x+=tlength;
23412 42 ++msgptr;
23413 42 ++msgpos;
23414
23415 // The "Continue From Previous" feature
23416
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23417 {
23418 if(MsgStrings[msgstr].nextstring)
23419 {
23420 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23421 {
23422 msgstr=MsgStrings[msgstr].nextstring;
23423 msgpos=msgptr=0;
23424 msgfont=setmsgfont();
23425 }
23426 }
23427 }
23428 }
23429 17 }
23430
23431 reparsesinglechar:
23432 // Continue printing the string!
23433
2/4
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 683 times.
1366 if(!atend(MsgStrings[msgstr].s.c_str()+msgptr) && !bottom_margin_clip())
23434 {
23435
3/6
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 683 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 683 times.
683 if(!do_run_menu && !doing_name_insert && !parsemsgcode())
23436 {
23437 683 wrapmsgstr(s3);
23438
23439 683 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23440
23441
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
686 if(cursor_x+tlength > (msg_w-msg_margins[right])
23442
4/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 680 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
683 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23443 2 ? true : strcmp(s3," ")!=0))
23444 {
23445
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23446 3 ssc_tile_hei = ssc_tile_hei_buf;
23447 3 ssc_tile_hei_buf = -1;
23448 3 cursor_y += thei + MsgStrings[msgstr].vspace;
23449
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(bottom_margin_clip()) goto strendcheck;
23450 3 cursor_x=msg_margins[left];
23451 //if(space) s3[0]=0;
23452 3 }
23453
23454 683 sfx(MsgStrings[msgstr].sfx);
23455
23456 683 char buf[2] = {0};
23457 683 sprintf(buf,"%c",MsgStrings[msgstr].s[msgptr]);
23458
23459 683 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23460
23461 683 cursor_x += msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]);
23462 683 cursor_x += MsgStrings[msgstr].hspace;
23463 683 msgpos++;
23464 683 }
23465
1/2
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
683 if(do_end_str)
23466 goto strendcheck;
23467
1/2
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
683 if(wait_advance)
23468 {
23469 ++msgptr;
23470 return;
23471 }
23472
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 683 times.
683 else if(do_run_menu)
23473 {
23474 if(runMenuCursor())
23475 {
23476 do_run_menu = false;
23477 ++msgptr;
23478 goto reparsesinglechar;
23479 }
23480 }
23481
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 683 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
683 else if(doing_name_insert && *nameptr)
23482 {
23483 char s3[9] = {0};
23484
23485 if(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP)
23486 {
23487 strcpy(s3, nameptr);
23488 }
23489 else
23490 {
23491 s3[0] = *nameptr;
23492 s3[1] = 0;
23493 }
23494
23495 tlength = text_length(msgfont, s3) + ((int32_t)strlen(s3)*MsgStrings[msgstr].hspace);
23496
23497 if(cursor_x+tlength > (msg_w-msg_margins[right])
23498 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23499 ? true : strcmp(s3," ")!=0))
23500 {
23501 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23502 ssc_tile_hei = ssc_tile_hei_buf;
23503 ssc_tile_hei_buf = -1;
23504 cursor_y += thei + MsgStrings[msgstr].vspace;
23505 if(bottom_margin_clip()) goto strendcheck;
23506 cursor_x=msg_margins[left];
23507 }
23508
23509 sfx(MsgStrings[msgstr].sfx);
23510
23511 char buf[2] = {0};
23512 sprintf(buf,"%c",*nameptr);
23513
23514 textout_styled_aligned_ex(msg_txt_bmp_buf,msgfont,buf,cursor_x,cursor_y,msg_shdtype,sstaLEFT,msgcolour,msg_shdcol,-1);
23515
23516 cursor_x += msgfont->vtable->char_length(msgfont, *nameptr);
23517 cursor_x += MsgStrings[msgstr].hspace;
23518 ++nameptr;
23519 }
23520 else
23521 {
23522 683 doing_name_insert = false;
23523 683 msgptr++;
23524
23525
2/2
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 17 times.
683 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23526 {
23527
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
17 if(MsgStrings[msgstr].nextstring)
23528 {
23529
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23530 {
23531 msgstr=MsgStrings[msgstr].nextstring;
23532 msgpos=msgptr=0;
23533 msgfont=setmsgfont();
23534 }
23535 3 }
23536 17 }
23537
23538
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 46 times.
821 if(MsgStrings[msgstr].s.size() > unsigned(msgptr+1)
23539
1/2
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
683 && (MsgStrings[msgstr].s[msgptr]==' ')
23540
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 545 times.
683 && (MsgStrings[msgstr].s[msgptr+1]==' '))
23541 {
23542
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 1219 times.
1265 while(MsgStrings[msgstr].s[msgptr]==' ')
23543 {
23544 1219 msgspace = true;
23545 1219 tlength = msgfont->vtable->char_length(msgfont, MsgStrings[msgstr].s[msgptr]) + MsgStrings[msgstr].hspace;
23546
23547
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 58 times.
1278 if(cursor_x+tlength > (msg_w-msg_margins[right])
23548
4/6
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 1160 times.
✓ Branch 2 taken 59 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 58 times.
✗ Branch 5 not taken.
1219 && ((cursor_x > (msg_w-msg_margins[right]) || !(MsgStrings[msgstr].stringflags & STRINGFLAG_WRAP))
23549 1 ? true : strcmp(s3," ")!=0))
23550 {
23551
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 int32_t thei = zc_max(ssc_tile_hei, text_height(msgfont));
23552 59 ssc_tile_hei = ssc_tile_hei_buf;
23553 59 ssc_tile_hei_buf = -1;
23554 59 cursor_y += thei + MsgStrings[msgstr].vspace;
23555
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if(bottom_margin_clip()) break;
23556 59 cursor_x=msg_margins[left];
23557 59 }
23558
23559 1219 cursor_x+=tlength;
23560 1219 ++msgpos;
23561 1219 ++msgptr;
23562
23563
2/2
✓ Branch 0 taken 150 times.
✓ Branch 1 taken 1069 times.
1219 if(atend(MsgStrings[msgstr].s.c_str()+msgptr))
23564 {
23565
2/2
✓ Branch 0 taken 760 times.
✓ Branch 1 taken 309 times.
1069 if(MsgStrings[msgstr].nextstring)
23566 {
23567
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 if(MsgStrings[MsgStrings[msgstr].nextstring].stringflags & STRINGFLAG_CONT)
23568 {
23569 msgstr=MsgStrings[msgstr].nextstring;
23570 msgpos=msgptr=0;
23571 msgfont=setmsgfont();
23572 }
23573 309 }
23574 1069 }
23575 }
23576 46 }
23577 }
23578 683 }
23579 strendcheck:
23580 // Done printing the string
23581
9/14
✓ Branch 0 taken 683 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 683 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 683 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 683 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 666 times.
✓ Branch 9 taken 17 times.
✓ Branch 10 taken 666 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 666 times.
✓ Branch 13 taken 17 times.
683 if(do_end_str || !doing_name_insert && !do_run_menu && (msgpos>=10000 || msgptr>=MsgStrings[msgstr].s.size() || bottom_margin_clip() || atend(MsgStrings[msgstr].s.c_str()+msgptr)) && !linkedmsgclk)
23582 {
23583
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!do_end_str)
23584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 while(parsemsgcode()); // Finish remaining control codes
23585
23586 // Go to next string, or make it disappear by going to string 0.
23587
5/6
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13 times.
17 if(MsgStrings[msgstr].nextstring!=0 || get_bit(quest_rules,qr_MSGDISAPPEAR) || enqueued_str)
23588 {
23589 4 linkedmsgclk=do_end_str?1:51;
23590 4 }
23591
23592
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
17 if(MsgStrings[msgstr].nextstring==0)
23593 {
23594
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
14 if(!get_bit(quest_rules,qr_MSGDISAPPEAR))
23595 13 {
23596 disappear:
23597 14 msg_active = false;
23598 14 Hero.finishedmsg();
23599 14 }
23600
23601
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if(repaircharge)
23602 {
23603 // if (get_bit(quest_rules,qr_REPAIRFIX)) {
23604 // fixed_door=true;
23605 // }
23606 game->change_drupy(-tmpscr[currscr<128?0:1].catchall);
23607 repaircharge = 0;
23608 }
23609
23610
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if(adjustmagic)
23611 {
23612 if(get_bit(quest_rules,qr_OLD_HALF_MAGIC))
23613 {
23614 if(game->get_magicdrainrate())
23615 game->set_magicdrainrate(1);
23616 }
23617 else if(game->get_magicdrainrate() > 1)
23618 {
23619 game->set_magicdrainrate(game->get_magicdrainrate()/2);
23620 }
23621 adjustmagic = false;
23622 sfx(WAV_SCALE);
23623 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
23624 }
23625
23626
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if(learnslash)
23627 {
23628 game->set_canslash(1);
23629 learnslash = false;
23630 sfx(WAV_SCALE);
23631 setmapflag((currscr < 128 && get_bit(quest_rules, qr_ITEMPICKUPSETSBELOW)) ? mITEM : mSPECIALITEM);
23632 }
23633 15 }
23634 18 }
23635 77941 }
23636
23637 197 int32_t message_more_y()
23638 {
23639 //Is the flag ticked, do we really want a message more y larger than 160?
23640
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 197 times.
✓ Branch 2 taken 197 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 197 times.
✗ Branch 5 not taken.
197 int32_t msgy=zc_min((zinit.msg_more_is_offset==0)?zinit.msg_more_y:zinit.msg_more_y+MsgStrings[msgstr].y ,160);
23641 197 msgy+=playing_field_offset;
23642 197 return msgy;
23643 }
23644
23645 /*** Collision detection & handling ***/
23646
23647 77857 void clear_script_one_frame_conditions()
23648 {
23649
2/2
✓ Branch 0 taken 196854 times.
✓ Branch 1 taken 77857 times.
274711 for(int32_t j=0; j<guys.Count(); j++)
23650 {
23651 196854 enemy *e = (enemy*)guys.spr(j);
23652
2/2
✓ Branch 0 taken 3149664 times.
✓ Branch 1 taken 196854 times.
3346518 for ( int32_t q = 0; q < NUM_HIT_TYPES_USED; q++ ) e->hitby[q] = 0;
23653 196854 }
23654 77857 }
23655
23656 77848 void check_collisions()
23657 {
23658 77848 bool temp_hit = false;
23659
2/2
✓ Branch 0 taken 21693 times.
✓ Branch 1 taken 77848 times.
99541 for(int32_t i=0; i<Lwpns.Count(); i++)
23660 {
23661 21693 weapon *w = (weapon*)Lwpns.spr(i);
23662
23663
6/8
✓ Branch 0 taken 15938 times.
✓ Branch 1 taken 5755 times.
✓ Branch 2 taken 11959 times.
✓ Branch 3 taken 3979 times.
✓ Branch 4 taken 11959 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 11959 times.
21693 if(!(w->Dead()) && w->id!=wSword && w->id!=wHammer && w->id!=wWand)
23664 {
23665
2/2
✓ Branch 0 taken 11808 times.
✓ Branch 1 taken 20871 times.
32679 for(int32_t j=0; j<guys.Count(); j++)
23666 {
23667 20871 enemy *e = (enemy*)guys.spr(j);
23668
2/2
✓ Branch 0 taken 445 times.
✓ Branch 1 taken 20426 times.
20871 if ( !temp_hit ) e->hitby[HIT_BY_LWEAPON] = 0;
23669
23670
2/2
✓ Branch 0 taken 20439 times.
✓ Branch 1 taken 432 times.
20871 if(e->hit(w)) //boomerangs and such that last for more than a frame can write hitby[] for more than one frame,
23671 //because this only checks `if(dying || clk<0 || hclk>0 || superman)`
23672 {
23673 // !(e->stunclk)
23674 432 int32_t h = e->takehit(w);
23675
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
432 if (h == -1)
23676 {
23677 432 e->hitby[HIT_BY_LWEAPON] = i+1; temp_hit = true;
23678 432 e->hitby[HIT_BY_LWEAPON_UID] = w->script_UID;
23679 //e->hitby[HIT_BY_LWEAPON_FAMILY] = itemsbuf[w->parentid].family; //that would be the itemclass, not the weapon type!
23680 432 e->hitby[HIT_BY_LWEAPON_FAMILY] = w->id;
23681 //al_trace("npc->HitBy[] Parent Item is: %d /n", w->parentitem);
23682 //al_trace("npc->HitBy[] Parent ID is: %d /n", w->parentid);
23683 432 e->hitby[HIT_BY_LWEAPON_LITERAL_ID] = w->parentitem;
23684
23685 432 }
23686 //we may need to handle this in special cases. -Z
23687
23688 //if h == stun or ignore
23689
23690 //if e->stun > DEFAULT_STUN -1 || !e->stun
23691 //if the enemy wasn't stunned this round -- what a bitch, as the stun value is set before we check this
23692 ///! how about: if w->dead != bounce !
23693
23694 // NOT FOR PUBLIC RELEASE
23695 /*if(h==3) //Mirror shield
23696 {
23697 if (w->id==ewFireball || w->id==wRefFireball)
23698 {
23699 w->id=wRefFireball;
23700 switch(e->dir)
23701 {
23702 case up: e->angle += (PI - e->angle) * 2.0; break;
23703 case down: e->angle = -e->angle; break;
23704 case left: e->angle += ((-PI/2) - e->angle) * 2.0; break;
23705 case right: e->angle += (( PI/2) - e->angle) * 2.0; break;
23706 // TODO: the following. -L.
23707 case l_up: break;
23708 case r_up: break;
23709 case l_down: break;
23710 case r_down: break;
23711 }
23712 }
23713 else
23714 {
23715 w->id = ((w->id==ewMagic || w->id==wRefMagic || w->id==wMagic) ? wRefMagic : wRefBeam);
23716 w->dir ^= 1;
23717 if(w->dir&2)
23718 w->flip ^= 1;
23719 else
23720 w->flip ^= 2;
23721 }
23722 w->ignoreHero=false;
23723 }
23724 else*/
23725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
432 if(h)
23726 {
23727
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
432 if(e->switch_hooked && w->family_class == itype_switchhook)
23728 w->onhit(false, e, -1);
23729 432 else w->onhit(false, e, h);
23730 432 }
23731
23732
1/2
✓ Branch 0 taken 432 times.
✗ Branch 1 not taken.
432 if(h==2)
23733 {
23734 break;
23735 }
23736 432 }
23737
23738
2/2
✓ Branch 0 taken 20720 times.
✓ Branch 1 taken 151 times.
20871 if(w->Dead())
23739 {
23740 151 break;
23741 }
23742 20720 }
23743
23744 // Item flags added in 2.55:
23745 // BRang/HShot/Arrows ITEM_FLAG4 is "Pick up anything" (port of qr_BRANGPICKUP)
23746 // BRang/HShot ITEM_FLAG5 is "Drags Items" (port of qr_Z3BRANG_HSHOT)
23747 // Arrows ITEM_FLAG2 is "Picks up items" (inverse port of qr_Z3BRANG_HSHOT)
23748 // -V
23749
4/6
✓ Branch 0 taken 7820 times.
✓ Branch 1 taken 4139 times.
✓ Branch 2 taken 7820 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 7820 times.
11959 if(w->id == wBrang || w->id == wHookshot || w->id == wArrow)
23750 {
23751 4139 int32_t itype, pitem = w->parentitem;
23752
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4139 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4139 switch(w->id)
23753 {
23754 4139 case wBrang: itype = itype_brang; break;
23755 case wArrow: itype = itype_arrow; break;
23756 case wHookshot:
23757 itype = (w->family_class == itype_switchhook ? itype_switchhook :itype_hookshot);
23758 break;
23759 }
23760
1/2
✓ Branch 0 taken 4139 times.
✗ Branch 1 not taken.
4139 if(pitem < 0) pitem = current_item_id(itype);
23761
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4139 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4139 if(w->id == wHookshot && w->family_class == itype_switchhook && (itemsbuf[pitem].flags & ITEM_FLAG9))
23762 { //Swap with item
23763 for(int32_t j=0; j<items.Count(); j++)
23764 {
23765 if(items.spr(j)->hit(w))
23766 {
23767 item *theItem = ((item*)items.spr(j));
23768 bool priced = theItem->PriceIndex >-1;
23769 bool isKey = itemsbuf[theItem->id].family==itype_key||itemsbuf[theItem->id].family==itype_lkey;
23770 if(!theItem->fallclk && !theItem->drownclk && ((theItem->pickup & ipTIMER && theItem->clk2 >= 32)
23771 || (((itemsbuf[w->parentitem].flags & ITEM_FLAG4)||(theItem->pickup & ipCANGRAB)||((itemsbuf[w->parentitem].flags & ITEM_FLAG7)&&isKey)) && !priced && !(theItem->pickup & ipDUMMY))))
23772 {
23773 if(!Hero.switchhookclk)
23774 {
23775 hooked_combopos = -1;
23776 hooked_layerbits = 0;
23777 switching_object = theItem;
23778 theItem->switch_hooked = true;
23779 w->misc = 2;
23780 w->step = 0;
23781 theItem->clk2=256;
23782 Hero.doSwitchHook(game->get_switchhookstyle());
23783 if(QMisc.miscsfx[sfxSWITCHED])
23784 sfx(QMisc.miscsfx[sfxSWITCHED],int32_t(w->x));
23785 }
23786 }
23787 }
23788 }
23789 }
23790
5/6
✗ Branch 0 not taken.
✓ Branch 1 taken 4139 times.
✓ Branch 2 taken 3878 times.
✓ Branch 3 taken 3878 times.
✓ Branch 4 taken 4139 times.
✓ Branch 5 taken 3878 times.
4139 else if((w->id==wArrow&&itemsbuf[pitem].flags & ITEM_FLAG2)||(w->id!=wArrow&&!(itemsbuf[pitem].flags & ITEM_FLAG5)))//An arrow with "Picks up items" or a BRang/HShot without "Drags items"
23791 {
23792
2/2
✓ Branch 0 taken 709 times.
✓ Branch 1 taken 3878 times.
4587 for(int32_t j=0; j<items.Count(); j++)
23793 {
23794
2/2
✓ Branch 0 taken 661 times.
✓ Branch 1 taken 48 times.
709 if(items.spr(j)->hit(w))
23795 {
23796 48 item *theItem = ((item*)items.spr(j));
23797 48 bool priced = theItem->PriceIndex >-1;
23798
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 bool isKey = itemsbuf[theItem->id].family==itype_key||itemsbuf[theItem->id].family==itype_lkey;
23799
4/8
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 31 times.
79 if(!theItem->fallclk && !theItem->drownclk && ((theItem->pickup & ipTIMER && theItem->clk2 >= 32)
23800
4/6
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 31 times.
48 || (((itemsbuf[pitem].flags & ITEM_FLAG4)||(theItem->pickup & ipCANGRAB)||((itemsbuf[pitem].flags & ITEM_FLAG7)&&isKey))&& !priced)))
23801 {
23802
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
79 if(itemsbuf[theItem->id].collect_script)
23803 {
23804 ZScriptVersion::RunScript(SCRIPT_ITEM, itemsbuf[theItem->id].collect_script, theItem->id & 0xFFF);
23805 }
23806
23807 17 Hero.checkitems(j);
23808 17 }
23809 48 }
23810 709 }
23811 3878 }
23812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
8017 else if(w->id!=wArrow) //A BRang/HShot with "Drags Items"
23813 {
23814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 for(int32_t j=0; j<items.Count(); j++)
23815 {
23816 if(items.spr(j)->hit(w))
23817 {
23818 item *theItem = ((item*)items.spr(j));
23819 bool priced = theItem->PriceIndex >-1;
23820 bool isKey = itemsbuf[theItem->id].family==itype_key||itemsbuf[theItem->id].family==itype_lkey;
23821 if(!theItem->fallclk && !theItem->drownclk && ((theItem->pickup & ipTIMER && theItem->clk2 >= 32)
23822 || (((itemsbuf[pitem].flags & ITEM_FLAG4)||(theItem->pickup & ipCANGRAB)||((itemsbuf[pitem].flags & ITEM_FLAG7)&&isKey)) && !priced && !(theItem->pickup & ipDUMMY))))
23823 {
23824 int32_t pickup = theItem->pickup;
23825 int32_t id2 = theItem->id;
23826 int32_t pstr = theItem->pstring;
23827 int32_t pstr_flags = theItem->pickup_string_flags;
23828
23829 std::vector<int32_t> &ev = FFCore.eventData;
23830 ev.clear();
23831 ev.push_back(id2*10000);
23832 ev.push_back(pickup*10000);
23833 ev.push_back(pstr*10000);
23834 ev.push_back(pstr_flags*10000);
23835 ev.push_back(0);
23836 ev.push_back(theItem->getUID());
23837 ev.push_back(GENEVT_ICTYPE_RANGED_DRAG*10000);
23838 ev.push_back(w->getUID());
23839
23840 throwGenScriptEvent(GENSCR_EVENT_COLLECT_ITEM);
23841 bool nullify = ev[4] != 0;
23842 if(nullify) continue;
23843 if(w->id == wBrang)
23844 {
23845 w->onhit(false);
23846 }
23847
23848 if(w->dragging==-1)
23849 {
23850 w->dead=1;
23851 theItem->clk2=256;
23852 w->dragging=j;
23853 theItem->is_dragged = true;
23854 }
23855 }
23856 }
23857 }
23858 261 }
23859 4139 }
23860 11959 }
23861 21693 }
23862 77848 }
23863
23864 77857 void dragging_item()
23865 {
23866
2/2
✓ Branch 0 taken 22166 times.
✓ Branch 1 taken 77857 times.
100023 for(int32_t i=0; i<Lwpns.Count(); i++)
23867 {
23868 22166 weapon *w = (weapon*)Lwpns.spr(i);
23869
23870
4/4
✓ Branch 0 taken 17949 times.
✓ Branch 1 taken 4217 times.
✓ Branch 2 taken 21906 times.
✓ Branch 3 taken 260 times.
22166 if((w->id == wBrang || w->id==wHookshot)&&itemsbuf[w->parentitem].flags & ITEM_FLAG5)//ITEM_FLAG5 is a port for qr_Z3BRANG_HSHOT
23871 {
23872
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 260 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
260 if(w->dragging>=0 && w->dragging<items.Count())
23873 {
23874 item* dragItem = (item*)items.spr(w->dragging);
23875 dragItem->x=w->x;
23876 dragItem->y=w->y;
23877
23878 // Drag the Fairy enemy as well as the Fairy item
23879 int32_t id = dragItem->id;
23880
23881 if(itemsbuf[id].family ==itype_fairy && itemsbuf[id].misc3)
23882 {
23883 movefairynew2(w->x,w->y,*dragItem);
23884 }
23885 }
23886 260 }
23887 22166 }
23888 77857 }
23889
23890 3 int32_t more_carried_items()
23891 {
23892 3 int32_t hasmorecarries = 0;
23893
23894
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for(int32_t i=0; i<items.Count(); i++)
23895 {
23896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if(((item*)items.spr(i))->pickup & ipENEMY)
23897 {
23898 3 hasmorecarries++;
23899 3 }
23900 3 }
23901
23902 3 return hasmorecarries;
23903 }
23904
23905 // messy code to do the enemy-carrying-the-item thing
23906 77857 void roaming_item()
23907 {
23908
4/4
✓ Branch 0 taken 754 times.
✓ Branch 1 taken 77103 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 751 times.
77857 if(!(hasitem&(4|2)) || !loaded_enemies)
23909 77106 return;
23910
23911 // All enemies already dead upon entering a room?
23912
1/2
✓ Branch 0 taken 751 times.
✗ Branch 1 not taken.
751 if(guys.Count()==0)
23913 {
23914 return;
23915 }
23916
23917 // Lost track of the carrier?
23918
3/6
✓ Branch 0 taken 751 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 751 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 751 times.
✗ Branch 5 not taken.
751 if(guycarryingitem<0 || guycarryingitem>=guys.Count() ||
23919 751 !((enemy*)guys.spr(guycarryingitem))->itemguy)
23920 {
23921 guycarryingitem=-1;
23922 for(int32_t j=0; j<guys.Count(); j++)
23923 {
23924 if(((enemy*)guys.spr(j))->itemguy)
23925 {
23926 guycarryingitem=j;
23927 break;
23928 }
23929 }
23930 }
23931
23932
2/2
✓ Branch 0 taken 748 times.
✓ Branch 1 taken 3 times.
751 if(hasitem&4)
23933 {
23934 3 guycarryingitem = -1;
23935
23936
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 3 times.
18 for(int32_t i=0; i<guys.Count(); i++)
23937 {
23938
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 3 times.
15 if(((enemy*)guys.spr(i))->itemguy)
23939 {
23940 3 guycarryingitem = i;
23941 3 }
23942 15 }
23943
23944
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if(guycarryingitem == -1) //This happens when "default enemies" such as
23945 {
23946 return; //eSHOOTFBALL are alive but enemies from the list
23947 } //are not. Defer to HeroClass::checkspecial().
23948
23949 3 int32_t Item=tmpscr->item;
23950
23951 3 hasitem &= ~4;
23952
23953
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 if((!getmapflag(mITEM) || (tmpscr->flags9&fITEMRETURN)) && (tmpscr->hasitem != 0))
23954 {
23955 6 additem(0,0,Item,ipENEMY+ipONETIME+ipBIGRANGE
23956
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 + (((tmpscr->flags3&fHOLDITEM) || (itemsbuf[Item].family==itype_triforcepiece)) ? ipHOLDUP : 0)
23957 );
23958 3 hasitem |= 2;
23959 3 }
23960 else
23961 {
23962 return;
23963 }
23964 3 }
23965
23966
2/2
✓ Branch 0 taken 751 times.
✓ Branch 1 taken 751 times.
1502 for(int32_t i=0; i<items.Count(); i++)
23967 {
23968
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 751 times.
751 if(((item*)items.spr(i))->pickup&ipENEMY)
23969 {
23970
2/2
✓ Branch 0 taken 327 times.
✓ Branch 1 taken 424 times.
751 if(get_bit(quest_rules,qr_HIDECARRIEDITEMS))
23971 {
23972 424 items.spr(i)->x = -128; // Awfully inelegant, innit?
23973 424 items.spr(i)->y = -128;
23974 424 }
23975
2/4
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 327 times.
327 else if(guycarryingitem>=0 && guycarryingitem<guys.Count())
23976 {
23977
1/2
✓ Branch 0 taken 327 times.
✗ Branch 1 not taken.
327 if (!get_bit(quest_rules, qr_BROKEN_ITEM_CARRYING))
23978 {
23979 if (get_bit(quest_rules, qr_ENEMY_DROPS_USE_HITOFFSETS))
23980 {
23981 items.spr(i)->x = guys.spr(guycarryingitem)->x+guys.spr(guycarryingitem)->hxofs+(guys.spr(guycarryingitem)->hxsz/2)-8;
23982 items.spr(i)->y = guys.spr(guycarryingitem)->y+guys.spr(guycarryingitem)->hyofs+(guys.spr(guycarryingitem)->hysz/2)-10;
23983 }
23984 else
23985 {
23986 if(guys.spr(guycarryingitem)->extend >= 3)
23987 {
23988 items.spr(i)->x = guys.spr(guycarryingitem)->x+(guys.spr(guycarryingitem)->txsz-1)*8;
23989 items.spr(i)->y = guys.spr(guycarryingitem)->y-2+(guys.spr(guycarryingitem)->tysz-1)*8;
23990 }
23991 else
23992 {
23993 items.spr(i)->x = guys.spr(guycarryingitem)->x;
23994 items.spr(i)->y = guys.spr(guycarryingitem)->y - 2;
23995 }
23996 }
23997 items.spr(i)->z = guys.spr(guycarryingitem)->z;
23998 items.spr(i)->fakez = guys.spr(guycarryingitem)->fakez;
23999 }
24000 else
24001 {
24002 327 items.spr(i)->x = guys.spr(guycarryingitem)->x;
24003 327 items.spr(i)->y = guys.spr(guycarryingitem)->y - 2;
24004 327 items.spr(i)->fakez = guys.spr(guycarryingitem)->fakez;
24005 }
24006 327 }
24007 751 }
24008 751 }
24009 77857 }
24010
24011 bool enemy::IsBigAnim()
24012 {
24013 return (anim == a2FRMB || anim == a4FRM8EYEB || anim == a4FRM4EYEB
24014 || anim == a4FRM8DIRFB || anim == a4FRM4DIRB || anim == a4FRM4DIRFB
24015 || anim == a4FRM8DIRB);
24016 }
24017
24018 const char *old_guy_string[OLDMAXGUYS] =
24019 {
24020 "(None)","Abei","Ama","Merchant","Moblin","Fire","Fairy","Goriya","Zelda","Abei 2","Empty","","","","","","","","","",
24021 // 020
24022 "Octorok (L1, Slow)","Octorok (L2, Slow)","Octorok (L1, Fast)","Octorok (L2, Fast)","Tektite (L1)",
24023 // 025
24024 "Tektite (L2)","Leever (L1)","Leever (L2)","Moblin (L1)","Moblin (L2)",
24025 // 030
24026 "Lynel (L1)","Lynel (L2)","Peahat (L1)","Zora","Rock",
24027 // 035
24028 "Ghini (L1, Normal)","Ghini (L1, Phantom)","Armos","Keese (CSet 7)","Keese (CSet 8)",
24029 // 040
24030 "Keese (CSet 9)","Stalfos (L1)","Gel (L1, Normal)","Zol (L1, Normal)","Rope (L1)",
24031 // 045
24032 "Goriya (L1)","Goriya (L2)","Trap (4-Way)","Wall Master","Darknut (L1)",
24033 // 050
24034 "Darknut (L2)","Bubble (Sword, Temporary Disabling)","Vire (Normal)","Like Like","Gibdo",
24035 // 055
24036 "Pols Voice (Arrow)","Wizzrobe (Teleporting)","Wizzrobe (Floating)","Aquamentus (Facing Left)","Moldorm",
24037 // 060
24038 "Dodongo","Manhandla (L1)","Gleeok (1 Head)","Gleeok (2 Heads)","Gleeok (3 Heads)",
24039 // 065
24040 "Gleeok (4 Heads)","Digdogger (1 Kid)","Digdogger (3 Kids)","Digdogger Kid (1)","Digdogger Kid (2)",
24041 // 070
24042 "Digdogger Kid (3)","Digdogger Kid (4)","Gohma (L1)","Gohma (L2)","Lanmola (L1)",
24043 // 075
24044 "Lanmola (L2)","Patra (L1, Big Circle)","Patra (L1, Oval)","Ganon","Stalfos (L2)",
24045 // 080
24046 "Rope (L2)","Bubble (Sword, Permanent Disabling)","Bubble (Sword, Re-enabling)","Shooter (Fireball)","Item Fairy ",
24047 // 085
24048 "Fire","Octorok (Magic)", "Darknut (Death Knight)", "Gel (L1, Tribble)", "Zol (L1, Tribble)",
24049 // 090
24050 "Keese (Tribble)", "Vire (Tribble)", "Darknut (Splitting)", "Aquamentus (Facing Right)", "Manhandla (L2)",
24051 // 095
24052 "Trap (Horizontal, Line of Sight)", "Trap (Vertical, Line of Sight)", "Trap (Horizontal, Constant)", "Trap (Vertical, Constant)", "Wizzrobe (Fire)",
24053 // 100
24054 "Wizzrobe (Wind)", "Ceiling Master ", "Floor Master ", "Patra (BS Zelda)", "Patra (L2)",
24055 // 105
24056 "Patra (L3)", "Bat", "Wizzrobe (Bat)", "Wizzrobe (Bat 2) ", "Gleeok (Fire, 1 Head)",
24057 // 110
24058 "Gleeok (Fire, 2 Heads)", "Gleeok (Fire, 3 Heads)","Gleeok (Fire, 4 Heads)", "Wizzrobe (Mirror)", "Dodongo (BS Zelda)",
24059 // 115
24060 "Dodongo (Fire) ","Trigger", "Bubble (Item, Temporary Disabling)", "Bubble (Item, Permanent Disabling)", "Bubble (Item, Re-enabling)",
24061 // 120
24062 "Stalfos (L3)", "Gohma (L3)", "Gohma (L4)", "NPC 1 (Standing) ", "NPC 2 (Standing) ",
24063 // 125
24064 "NPC 3 (Standing) ", "NPC 4 (Standing) ", "NPC 5 (Standing) ", "NPC 6 (Standing) ", "NPC 1 (Walking) ",
24065 // 130
24066 "NPC 2 (Walking) ", "NPC 3 (Walking) ", "NPC 4 (Walking) ", "NPC 5 (Walking) ", "NPC 6 (Walking) ",
24067 // 135
24068 "Boulder", "Goriya (L3)", "Leever (L3)", "Octorok (L3, Slow)", "Octorok (L3, Fast)",
24069 // 140
24070 "Octorok (L4, Slow)", "Octorok (L4, Fast)", "Trap (8-Way) ", "Trap (Diagonal) ", "Trap (/, Constant) ",
24071 // 145
24072 "Trap (/, Line of Sight) ", "Trap (\\, Constant) ", "Trap (\\, Line of Sight) ", "Trap (CW, Constant) ", "Trap (CW, Line of Sight) ",
24073 // 150
24074 "Trap (CCW, Constant) ", "Trap (CCW, Line of Sight) ", "Wizzrobe (Summoner)", "Wizzrobe (Ice) ", "Shooter (Magic)",
24075 // 155
24076 "Shooter (Rock)", "Shooter (Spear)", "Shooter (Sword)", "Shooter (Fire)", "Shooter (Fire 2)",
24077 // 160
24078 "Bombchu", "Gel (L2, Normal)", "Zol (L2, Normal)", "Gel (L2, Tribble)", "Zol (L2, Tribble)",
24079 // 165
24080 "Tektite (L3) ", "Spinning Tile (Combo)", "Spinning Tile (Enemy Sprite)", "Lynel (L3) ", "Peahat (L2) ",
24081 // 170
24082 "Pols Voice (Magic) ", "Pols Voice (Whistle) ", "Darknut (Mirror) ", "Ghini (L2, Fire) ", "Ghini (L2, Magic) ",
24083 // 175
24084 "Grappler Bug (HP) ", "Grappler Bug (MP) "
24085 };
24086
24087 /*** end of guys.cc ***/
24088
24089